Nach Position oder Name
Argumente lassen sich nach Position (der Reihe nach den Parametern zugeordnet) oder nach Name (quantity=200) übergeben. Namen machen einen Aufruf lesbar, wenn eine Funktion mehrere Eingaben desselben Typs hat, und erlauben beliebige Reihenfolge. Positionsargumente müssen zuerst stehen; sobald Sie einen Namen verwenden, müssen auch die übrigen benannt sein.
def pnl(entry, exit_price, quantity):
return (exit_price - entry) * quantity
print(pnl(184.0, 185.5, 200)) # 300.0
print(pnl(quantity=200, entry=184.0, exit_price=185.5)) # 300.0Standardwerte machen Parameter optional
Schreiben Sie name=value in die def-Zeile, dann darf der Aufrufer das Argument weglassen; der Standardwert wird verwendet. Parameter mit Standardwert stehen nach denen ohne. Standardwerte passen zu Einstellungen, die meist gleich sind, etwa Gebührensatz oder Minimum, und jeder lässt sich weiterhin per Namen überschreiben.
# Parameters with a default are optional
def fee(notional, rate=0.001, minimum=1.0):
return max(minimum, notional * rate)
print(fee(36850.0)) # 36.85
print(fee(36850.0, rate=0.0005)) # 18.425
print(fee(100.0, minimum=0.5)) # 0.5Beliebig viele Argumente: *args
Ein Parameter *prices sammelt alle zusätzlichen Positionsargumente in einem Tupel, sodass average(1, 2, 3) und average(1, 2, 3, 4, 5) beide funktionieren. Beim Aufruf gilt das Umgekehrte: average(*quotes) entpackt eine Liste in einzelne Argumente.
# *prices collects the extra arguments into a tuple
def average(*prices):
return sum(prices) / len(prices)
print(average(184.0, 185.0, 186.0)) # 185.0
quotes = [184.0, 185.0]
print(average(*quotes)) # 184.5Beliebige benannte Optionen: **options
Genauso sammelt **options zusätzliche benannte Argumente in einem Dictionary aus Namen und Werten (Dictionaries bekommen bald ein eigenes Thema). Das passt zu Funktionen mit optionalen Extras, etwa Order-Einstellungen. sorted(options) liefert die Namen alphabetisch, sodass die Ausgabe vorhersehbar ist.
# **options collects extra named arguments into a dictionary
def describe(symbol, **options):
text = symbol
for name in sorted(options):
text += f" {name}={options[name]}"
return text
print(describe("AAPL", tif="day", limit=184.5)) # AAPL limit=184.5 tif=dayDie Falle des veränderbaren Standardwerts
Ein Standardwert wird einmal erzeugt, beim Definieren der Funktion, nicht bei jedem Aufruf. Bei einer Zahl oder einem Text ist das harmlos. Bei einer Liste teilen und verändern alle Aufrufe, die den Standardwert nutzen, dieselbe Liste. Die übliche Lösung: None als Standard und in der Funktion eine frische Liste anlegen.
# A default list is created once and shared by every call
def add_fill(fill, fills=[]):
fills.append(fill)
return fills
print(add_fill(100)) # [100]
print(add_fill(200)) # [100, 200] <- surprise: the same list
# The fix: default to None and build a new list inside
def add_fill_fixed(fill, fills=None):
if fills is None:
fills = []
fills.append(fill)
return fills
print(add_fill_fixed(100)) # [100]
print(add_fill_fixed(200)) # [200]- Verwenden Sie Namen bei Aufrufen mit mehreren Eingaben desselben Typs.
- Standardwerte für meist gleiche Einstellungen; nie eine Liste oder ein Dictionary.
*argsfür beliebig viele Werte,**optionsfür benannte Extras.
Als Nächstes: Gültigkeitsbereich und Closures, um zu sehen, welche Namen eine Funktion sieht und wie sie sich Werte merken kann.
Lab: Was bewertet wird
- Mit
position_pnlMenge und Seite optional machen25 Pkt. - Mit
averagebeliebig viele Preise annehmen25 Pkt. - Mit
describe_orderbenannte Order-Optionen entgegennehmen25 Pkt. - Mit
add_filldie Falle der geteilten Liste vermeiden25 Pkt.