Meer expressieve functies · oefening
Maak belangrijke argumenten expliciet
De vorige les liet zien dat keywordargumenten een functieaanroep leesbaarder kunnen maken. We kozen ervoor status="needs review" te schrijven in plaats van nog een onverklaarde string mee te geven.
Keywordargumenten waren echter alleen een keuze. Python zou de positionele versie nog steeds accepteren. Voor sommige instellingen willen we de namen liever verplicht stellen.
Bekijk een functie die een ingevoerd antwoord op twee verschillende manieren kan opschonen:
def normalize_response(
response,
ignore_case=False,
trim_spaces=True,
):
...
Probeer deze aanroep te lezen zonder terug te kijken naar de definitie:
normalize_response(" Python ", True, False)
De twee booleaanse waarden verklaren zichzelf niet. Betekent True “negeer hoofdletters” of “verwijder spaties”? Om dat te beantwoorden, moet een lezer de functiedefinitie opzoeken en elke positie zorgvuldig koppelen.
Verplicht de namen van instellingen
Python laat ons * vóór de instellingen in de functiedefinitie plaatsen:
def normalize_response(
response,
*,
ignore_case=False,
trim_spaces=True,
):
...
De * verdeelt de parameters in twee groepen:
responsestaat vóór*en mag dus nog op positie worden meegegeven.ignore_caseentrim_spacesstaan na*, dus hun namen zijn verplicht.
Parameters waarvan de namen verplicht zijn, heten keyword-only parameters. De leesbare aanroep is nu de enige geldige vorm:
normalize_response(
" KEEP CASE ",
ignore_case=False,
trim_spaces=True,
)
De * ontvangt geen waarde. Die verandert alleen hoe latere argumenten moeten worden meegegeven. Het functieblok kan ignore_case en trim_spaces blijven gebruiken als gewone booleaanse waarden.
Een keyword-only instelling positioneel meegeven veroorzaakt een TypeError voordat het functieblok wordt uitgevoerd.
Gebruik deze regel wanneer de namen duidelijkheid toevoegen
Namen verplicht stellen is vooral handig voor:
booleaanse schakelaars;
meerdere instellingen die hetzelfde waardetype gebruiken;
optionele keuzes die merkbaar veranderen wat een functie doet.
Niet elk argument heeft deze regel nodig. Een korte aanroep zoals round(3.14159, 2) is al bekend en compact. Keyword-only parameters helpen wanneer de toegevoegde namen een aanroep duidelijk begrijpelijker maken.
Wat gebeurt er wanneer de laatste regel wordt uitgevoerd?
def clean(text, *, lowercase=False):
if lowercase:
return text.lower()
return text
print(clean("Python", True))
De geldige aanroep is clean("Python", lowercase=True).
Herstel een ongeldige aanroep
De functie in de editor is al compleet, maar de aanroepende code geeft beide instellingen positioneel mee. Voer de startcode uit en lees de TypeError. Herstel daarna de aanroep door de twee keyword-only argumenten te benoemen. De afgedrukte tekens | maken overgebleven spaties zichtbaar.
Behoud de * in de functiedefinitie. Die verwijderen zou de fout verbergen in plaats van de onduidelijke aanroep te herstellen.
Opdracht
Voer de startcode uit en bekijk de TypeError. Herstel daarna de aanroep die result maakt.
Behoud
responseals positioneel argument.Geef
ignore_case=Trueals keywordargument mee.Geef
trim_spaces=Falseals keywordargument mee.Laat de
*, het functieblok en de laatsteprintongewijzigd.
Het herstelde programma moet | python | afdrukken. De strepen zijn alleen grenzen; de twee spaties aan elke kant van python horen bij result.