2009-05-28 11 views
245

In ähnlicher Weise varargs in C oder C++:Kann eine variable Anzahl von Argumenten an eine Funktion übergeben werden?

fn(a, b) 
fn(a, b, c, d, ...) 
+5

ich den Herrn lottness 53 Podcast: http://itc.conversationsnetwork.org/shows/detail4111.html?loomia_si=t0:a16:g2:r2: c0.246273: b24677090 –

+1

Ich muss mit Herrn Lott über diesen gehen. Sie können schnell eine autorisierende Antwort zu diesem Thema in den Python-Dokumenten erhalten, außerdem erhalten Sie ein Gefühl dafür, was sonst noch in den Dokumenten vorhanden ist. Es ist zu Ihrem Vorteil, diese Dokumente kennenzulernen, wenn Sie vorhaben, in Python zu arbeiten. –

+7

Die schnellste Antwort ist, was Google sagt, ist die schnellste Antwort. –

Antwort

319

Ja.

Das ist einfach und funktioniert, wenn Sie Keyword-Argumente außer Acht lassen:

def manyArgs(*arg): 
    print "I was called with", len(arg), "arguments:", arg 

>>> manyArgs(1) 
I was called with 1 arguments: (1,) 
>>> manyArgs(1, 2,3) 
I was called with 3 arguments: (1, 2, 3) 

Wie Sie Python sehen können, geben Sie ein einzelnes Tupel mit allen Argumenten.

Für Schlüsselwortargumente müssen Sie diese als separates tatsächliches Argument akzeptieren, wie in Skurmedel's answer gezeigt.

+10

http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions – Miles

+5

Auch wichtig ...Man kann eine Zeit finden, in der sie eine unbekannte Anzahl von Argumenten an eine Funktion übergeben müssen. In einem solchen Fall rufen Sie Ihre "manyArgs" auf, indem Sie eine Liste namens "args" erstellen und diese an vieleArgs wie "manyArgs (* args)" übergeben. – wilbbe01

+2

Das ist knapp, aber das ist leider nicht allgemein genug: 'manyArgs (x = 3) 'scheitert mit' TypeError'. Skumedels Antwort zeigt die Lösung dafür. Der entscheidende Punkt ist, dass die allgemeine Signatur einer Funktion 'f (* list_args, ** keyword_args)' ist (nicht 'f (* list_args)'). – EOL

179

Hinzufügen zu Abwicklungen Beitrag:

Sie können auch mehrere Schlüssel-Wert-args senden.

def myfunc(**kwargs): 
    # kwargs is a dictionary. 
    for k,v in kwargs.iteritems(): 
     print "%s = %s" % (k, v) 

myfunc(abc=123, efh=456) 
# abc = 123 
# efh = 456 

Und Sie können die mischen zwei:

def myfunc2(*args, **kwargs): 
    for a in args: 
     print a 
    for k,v in kwargs.iteritems(): 
     print "%s = %s" % (k, v) 

myfunc2(1, 2, 3, banan=123) 
# 1 
# 2 
# 3 
# banan = 123 

Sie müssen beide und in dieser Reihenfolge genannt deklariert werden, dh die Funktion Signatur benötigt * args sein, ** kwargs und rief in diese Reihenfolge.

+2

Nicht sicher, wie Sie myfunc (abc = 123, def = 456) zu arbeiten, aber in meiner (2.7) kann 'def' in dieser Funktion nicht übergeben werden, ohne einen SyntaxError zu bekommen. Ich nehme an, das liegt daran, dass def Bedeutung in Python hat. Versuchen Sie stattdessen myfunc (abc = 123, fgh = 567). (Sonst tolle Antwort und Danke dafür!) – Dannid

+0

@Dannid: Keine Ahnung, haha ​​... funktioniert auch nicht auf 2.6 oder 3.2. Ich werde es umbenennen. – Skurmedel

+0

Wenn Sie sagen "in dieser Reihenfolge angerufen", meinen Sie das in dieser Reihenfolge? Oder etwas anderes? –

11

Hinzufügen zu den anderen ausgezeichneten Beiträge.

Manchmal möchten Sie nicht die Anzahl der Argumente angeben und möchten Schlüssel für sie verwenden (der Compiler wird sich beschweren, wenn ein in einem Dictionary übergebenes Argument in der Methode nicht verwendet wird).

def manyArgs1(args): 
    print args.a, args.b #note args.c is not used here 

def manyArgs2(args): 
    print args.C#note args.b and .c are not used here 

class Args: pass 

args = Args() 
args.a = 1 
args.b = 2 
args.c = 3 

manyArgs1(args) #outputs 1 2 
manyArgs2(args) #outputs 3 

Dann können Sie Dinge tun, wie

myfuns = [manyArgs1, manyArgs2] 
for fun in myfuns: 
    fun(args) 
1
def f(dic): 
    if 'a' in dic: 
     print dic['a'], 
     pass 
    else: print 'None', 

    if 'b' in dic: 
     print dic['b'], 
     pass 
    else: print 'None', 

    if 'c' in dic: 
     print dic['c'], 
     pass 
    else: print 'None', 
    print 
    pass 
f({}) 
f({'a':20, 
    'c':30}) 
f({'a':20, 
    'c':30, 
    'b':'red'}) 
____________ 

die obige Code gibt

None None None 
20 None 30 
20 red 30 

Dies ist so gut wie variable Argumente mittels eines Wörterbuch vorbei

+3

Das ist ein schrecklicher Code. Viel besser wäre: 'f = lambda ** dic: '' .join (dic.get (key, 'None') für den Schlüssel in 'abc')' – metaperture

7

Wenn ich darf, Skurmedels c Ode ist für Python 2; Um es an Python 3 anzupassen, ändern Sie iteritems in items und fügen Sie Klammern print hinzu. Das könnte Anfänger wie mich daran hindern zu stoßen: AttributeError: 'dict' object has no attribute 'iteritems' und suchen Sie woanders (z. B. Error “ 'dict' object has no attribute 'iteritems' ” when trying to use NetworkX's write_shp()) warum das passiert.

def myfunc(**kwargs): 
for k,v in kwargs.items(): 
    print("%s = %s" % (k, v)) 

myfunc(abc=123, efh=456) 
# abc = 123 
# efh = 456 

und:

def myfunc2(*args, **kwargs): 
    for a in args: 
     print(a) 
    for k,v in kwargs.items(): 
     print("%s = %s" % (k, v)) 

myfunc2(1, 2, 3, banan=123) 
# 1 
# 2 
# 3 
# banan = 123 
Verwandte Themen