Python, domyślne argumenty słów kluczowych po argumentach pozycyjnych o zmiennej długości

82

Pomyślałem, że mogę użyć nazwanych parametrów po parametrach pozycyjnych o zmiennej długości w wywołaniu funkcji w Pythonie 2, ale otrzymuję SyntaxErrorpodczas importowania klasy Pythona. Piszę następującą metodą „pobierz”, na przykład:

class Foo(object):
    def __init__(self):
        print "You have created a Foo."

    def get(self, *args, raw=False, vars=None):
        print len(args)
        print raw
        print vars

Błąd wygląda następująco:

def get(self, *args, raw=False, vars=None):
                     ^
SyntaxError: invalid syntax

Chciałbym móc wywołać tę metodę na kilka sposobów:

f = Foo()
f.get(arg1, arg2)
f.get(arg1, raw=True)
f.get(arg1, arg2, raw=True, vars=something)

itp.

jkmacc
źródło

Odpowiedzi:

71

Działa, ale tylko w Pythonie 3. Zobacz PEP 3102 . Spoglądając na dokumenty „co nowego”, wydaje się, że nie ma backportu 2.x, więc nie masz szczęścia. Będziesz musiał zaakceptować argumenty słów kluczowych ( **kwargs) i ręcznie je przeanalizować. Możesz użyć, d.get(k, default)aby dostać d[k]lub defaultjeśli tego nie ma. Aby usunąć argument z kwargs, np. Przed wywołaniem metody superklasy, użyj d.pop.


Zauważ, że w def get(self, *args, raw=False, vars=None):programie raw=Falsei vars=Nonenie mają nic wspólnego z argumentami słów kluczowych. To są domyślne wartości argumentów. Argumenty z wartością domyślną mogą być przekazywane pozycyjnie, a argumenty bez wartości domyślnej mogą być przekazywane przez słowo kluczowe:

def f(a=1): pass
f(2)  # works, passing a positionally
def f(a): pass
f(a=2)  # works, passing a by keyword

Podobnie argumenty zawierające tylko słowa kluczowe nie muszą mieć wartości domyślnej. Po *argsargumencie jest to, co oznacza, że ​​są tylko słowami kluczowymi, a nie obecność wartości domyślnej:

def f(*args, a): pass
# a is a mandatory, keyword-only argument
funky-future
źródło
Dzięki tobie i Imranowi! Twoja odpowiedź z blokiem kodu Imrana i sugestią dotyczącą dokumentów doskonale odpowiedziała na pytanie.
jkmacc
50

Składnia Pythona nie zezwala na zmienne argumenty w argumentach funkcji i słów kluczowych z wartością domyślną w tym samym czasie. Jeśli musisz mieć argumenty słów kluczowych wraz z dowolną liczbą argumentów pozycyjnych, musisz również zezwolić na dowolną liczbę argumentów ze słów kluczowych.

Jest to typowy wzorzec zapewniający domyślne wartości argumentów słów kluczowych, a także zezwalający na dowolną liczbę argumentów pozycyjnych:

def foo(*args, **kwargs):
   raw = kwargs.pop('raw', False)
   vars = kwargs.pop('vars', None)

Jeśli w ogóle nie używasz dodatkowych argumentów słów kluczowych, nie masz się czym martwić. To sprawia, że ​​funkcja jest nieco mniej samodokumentująca, co można uzupełnić odpowiednio napisanym dokumentem.

Imran
źródło