Podczas gdy większość odpowiedzi mówi, że np.
def f(**kwargs):
foo = kwargs.pop('foo')
bar = kwargs.pop('bar')
...etc...
jest taki sam jak"
def f(foo=None, bar=None, **kwargs):
...etc...
to nie jest prawda. W drugim przypadku f
można wywołać jako f(23, 42)
, podczas gdy pierwszy przypadek przyjmuje tylko nazwane argumenty - bez wywołań pozycyjnych. Często chcesz pozwolić na maksymalną elastyczność abonenta wywołującego, dlatego preferowana jest druga forma, jak twierdzi większość odpowiedzi: ale nie zawsze tak jest. Gdy akceptujesz wiele opcjonalnych parametrów, z których zwykle tylko kilka jest przekazywanych, może być doskonałym pomysłem (unikanie wypadków i nieczytelnego kodu w witrynach połączeń!) Wymuszenie użycia nazwanych argumentów - threading.Thread
to przykład. Pierwszą formą jest sposób implementacji tego w Python 2.
Idiom jest tak ważne, że w Pythonie 3 ma teraz specjalną składnię pomocnicze: każdy argument, po jednokrotnym *
w def
podpisie jest tylko słowa kluczowe, czyli nie mogą być przekazywane jako argumentu pozycyjnym, ale tylko w nazwie jednego. Tak więc w Python 3 możesz zakodować powyższe jako:
def f(*, foo=None, bar=None, **kwargs):
...etc...
Rzeczywiście, w Pythonie 3 możesz nawet mieć argumenty zawierające tylko słowa kluczowe, które nie są opcjonalne (te bez wartości domyślnej).
Jednak Python 2 ma przed sobą długie lata produktywnego życia, więc lepiej nie zapominać o technikach i idiomach, które pozwalają wdrożyć w Pythonie 2 ważne pomysły projektowe, które są bezpośrednio obsługiwane w języku Python 3!