Python, Standardschlüsselwortargumente nach Positionsargumenten variabler Länge

81

Ich dachte, ich könnte benannte Parameter nach Positionsparametern variabler Länge in einem Funktionsaufruf in Python 2 verwenden, aber SyntaxErrorbeim Importieren einer Python-Klasse erhalte ich eine . Ich schreibe zum Beispiel mit der folgenden "get" -Methode:

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

Der Fehler sieht aus wie:

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

Ich möchte die Methode auf verschiedene Arten aufrufen können:

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

etc.

jkmacc
quelle

Antworten:

70

Es funktioniert, aber nur in Python 3. Siehe PEP 3102 . Wenn Sie sich die "neuen" Dokumente ansehen, scheint es keinen 2.x-Backport zu geben, sodass Sie kein Glück haben. Sie müssen alle Schlüsselwortargumente ( **kwargs) akzeptieren und manuell analysieren. Sie können verwenden, d.get(k, default)um entweder zu bekommen d[k]oder defaultwenn das nicht da ist. kwargsVerwenden Sie, um ein Argument zu entfernen , z. B. bevor Sie eine Methode der Superklasse aufrufen d.pop.


Beachten Sie, dass in def get(self, *args, raw=False, vars=None):, raw=Falseund vars=Nonenichts mit Schlüsselwortargumenten zu tun haben. Dies sind Standardargumentwerte. Argumente mit einem Standardwert können positionell übergeben werden, und Argumente ohne Standardwert können über das Schlüsselwort übergeben werden:

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

In ähnlicher Weise müssen Argumente nur für Schlüsselwörter keinen Standardwert haben. Nach dem *argsArgument werden sie als Nur-Schlüsselwort markiert, nicht als Standardwert:

def f(*args, a): pass
# a is a mandatory, keyword-only argument
Funky-Zukunft
quelle
Vielen Dank an Sie und Imran! Ihre Antwort mit Imrans Codeblock und Docstring-Vorschlag hat die Frage perfekt beantwortet.
Jkmacc
50

Die Python-Syntax erlaubt keine variablen Argumente in Funktions- und Schlüsselwortargumenten mit gleichzeitigem Standardwert. Wenn Sie Schlüsselwortargumente zusammen mit einer beliebigen Anzahl von Positionsargumenten haben müssen, müssen Sie auch eine beliebige Anzahl von Schlüsselwortargumenten zulassen.

Dies ist ein gängiges Muster, um Standardwerte für Schlüsselwortargumente bereitzustellen und eine beliebige Anzahl von Positionsargumenten zuzulassen:

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

Wenn Sie die zusätzlichen Schlüsselwortargumente überhaupt nicht verwenden, müssen Sie sich keine Sorgen machen. Dies macht die Funktion etwas weniger selbstdokumentierend, was Sie mit einem richtig geschriebenen Dokumentstring nachholen können.

Imran
quelle