2013-02-25 5 views
16

In Python können wir dies tun:Python: Parameter mit Namen Passing zusammen mit kwargs

def myFun1(one = '1', two = '2'): 
    ... 

Dann können wir die Funktion aufrufen und die Argumente durch ihren Namen übergeben:

myFun1(two = 'two', one = 'one')

Auch wir können dies tun:

def myFun2(**kwargs): 
    print kwargs.get('one', 'nothing here') 

myFun2(one='one')

Also habe ich mich gefragt, ob es möglich ist, beide Methoden zu kombinieren, wie:

def myFun3(name, lname, **other_info): 
    ... 

myFun3(lname='Someone', name='myName', city='cityName', otherInfo='blah')

Im Allgemeinen welche Kombinationen können wir tun?

Dank und sorry für meine dumme Frage

+1

bezogen: http://stackoverflow.com/questions/9872824/calling -a-python-function-with-args-kwargs-und-optional-default-arguments – mgilson

Antwort

19

Die allgemeine Idee ist:

def func(arg1, arg2, ..., kwarg1=default, kwarg2=default, ..., *args, **kwargs): 
    ... 

Sie können so viele von denen, wie Sie wollen. Die * und ** werden alle verbleibenden Werte "aufsaugen", die sonst nicht berücksichtigt werden.

Positionsargumente (ohne Angabe von Standardwerten) können nicht nach Schlüsselwörtern angegeben werden, und nicht standardmäßige Argumente können nicht den Standardargumenten folgen.

Hinweis Python 3 auch die Möglichkeit, nur für Schlüsselwort, indem sie nach * mit Argumenten angeben, fügt hinzu:

def func(arg1, arg2, *args, kwonlyarg=default): 
    ... 

Sie auch * allein

( def func(a1, a2, *, kw=d):), was bedeutet, können, dass keine Argumente erfasst werden, aber etwas nach ist nur ein Keyword.

Also, wenn Sie in 3.x sind, können Sie das Verhalten Sie wollen mit produzieren:

def myFun3(*, name, lname, **other_info): 
    ... 

die mit name und lname als Keyword-only Aufruf erlauben würde.

Beachten Sie, dass dies eine ungewöhnliche Schnittstelle ist, die für den Benutzer lästig sein kann - ich würde sie nur in sehr speziellen Anwendungsfällen verwenden.

In 2.x müssten Sie dies manuell vornehmen, indem Sie **kwargs analysieren.

+0

Vorsicht, ich glaube nicht, dass Sie Standardargumente nach * args haben können (zumindest nicht auf python2.x) – mgilson

+0

@mgilson I vergesse immer 2.x Fehler, behoben. –

+0

in Python 2.7 'Def Test (var, kwarg1 = 1, * args, ** kwargs): ...' funktioniert nicht für mich.beklagt sich über mehrere Werte für ein Schlüsselwortargument – Raufio

0

Es ist zumindest für Python 2.7 möglich. Stichwort Argumente erhalten, um Positionsparameter mit ihrem Namen zugewiesen, so können Sie

In [34]: def func(name, lname, **kwargs): 
    print 'name='+name, 'lname='+lname 
    print kwargs 
    ....:  

In [35]: func(lname='lname_val', name='name_val', city='cityName', otherInfo='blah') 
name=name_val lname=lname_val 
{'city': 'cityName', 'otherInfo': 'blah'} 

Offizielle docs es auf diese Weise angeben, tun. „Wenn Keyword-Argumente vorhanden sind, sind sie zunächst zu Positionsargumente umgewandelt, wie folgt zunächst ein Die Liste der ungefüllten Slots wird für die formalen Parameter erstellt.Wenn es N Positionsargumente gibt, werden sie in den ersten N Slots platziert.Als nächstes wird für jedes Schlüsselwortargument der Bezeichner verwendet, um den entsprechenden Slot zu bestimmen (wenn der Bezeichner der gleiche ist wie der erste Name des formalen Parameters, wird der erste Slot verwendet und so weiter). Wenn der Steckplatz bereits gefüllt ist, wird eine TypeError-Ausnahme ausgelöst. Andernfalls wird der Wert des Arguments im Slot platziert und gefüllt (auch wenn der Ausdruck "None" ist, füllt es den Slot). " https://docs.python.org/2/reference/expressions.html#calls