More Expressive Functions · practice
Make Important Arguments Explicit
The previous lesson showed that keyword status="needs review" instead of supplying one more unexplained
However, keyword arguments were only a choice. Python would still accept the positional version. For some settings, we would rather require the names.
Consider a function that can clean a response in two different ways:
def normalize_response(
response,
ignore_case=False,
trim_spaces=True,
):
...
Without looking back at the definition, try to read this call:
normalize_response(" Python ", True, False)
The two True mean “ignore letter case” or “trim spaces”? To answer, a reader must find the function definition and carefully match each position.
Require the setting names
Python lets us place * before the settings in the function definition:
def normalize_response(
response,
*,
ignore_case=False,
trim_spaces=True,
):
...
The * divides the
responsecomes before*, so it may still be supplied by position.ignore_caseandtrim_spacescome after*, so their names are required.
Parameters whose names are required are called keyword-only parameters. The readable call is now the only valid form:
normalize_response(
" KEEP CASE ",
ignore_case=False,
trim_spaces=True,
)
The * does not receive a ignore_case and trim_spaces as ordinary Boolean values.
Passing a keyword-only setting by position raises
Use this rule when the names add clarity
Requiring names is especially helpful for:
Boolean switches;
several settings that use the same type of value;
optional choices that noticeably change what a function does.
Not every argument needs this rule. A short call such as round(3.14159, 2) is already familiar and compact. Keyword-only parameters help when the added names make a call meaningfully easier to understand.
What happens when the final line runs?
def clean(text, *, lowercase=False):
if lowercase:
return text.lower()
return text
print(clean("Python", True))
The valid call is clean("Python", lowercase=True).
Repair an invalid call
The function in the editor is already complete, but the code that calls it supplies both settings by position. Run the starter code and read the TypeError. Then repair the call by naming the two keyword-only arguments. The printed | characters make any spaces that remain visible.
Keep the * in the function definition. Removing it would hide the mistake instead of fixing the unclear call.
Task
Run the starter code and inspect its result.
Keep
responseas the positional. Supply
ignore_case=Trueby keyword.Supply
trim_spaces=Falseby keyword.Keep the
*, thebody, and the final printunchanged.
The repaired program should print | python |. The bars are only boundaries; the two spaces on each side of python are part of result.