2009-05-28 15 views
245

De una manera similar al uso de varargs en C o C++:¿Se puede pasar una cantidad variable de argumentos a una función?

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

que se refieren al honorable lottness podcast 53: http://itc.conversationsnetwork.org/shows/detail4111.html?loomia_si=t0:a16:g2:r2: c0.246273: b24677090 –

+1

Tengo que ir con el Sr. Lott en este caso. Puede obtener rápidamente una respuesta de autoría en este documento de Python, además tendrá una idea de qué más hay en los documentos. Le conviene conocer esos documentos si planea trabajar en Python. –

+7

La respuesta más rápida es lo que Google dice es la respuesta más rápida. –

Respuesta

319

Sí.

Esto es simple y funciona si usted caso omiso de los argumentos de palabras clave:

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) 

Como se puede ver, Python le dará una única tupla con todos los argumentos.

Para los argumentos de palabra clave debe aceptarlos como un argumento real separado, como se muestra en Skurmedel's answer.

+10

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

+5

También es importante ...uno puede encontrar un momento en el que tienen que pasar una cantidad desconocida de argumentos a una función. En un caso como este, llame a su "manyArgs" creando una lista llamada "args" y pasando eso a manyArgs como este "manyArgs (* args)" – wilbbe01

+2

Esto está cerca, pero desafortunadamente no es lo suficientemente general: 'manyArgs (x = 3) 'falla con' TypeError'. La respuesta de Skumedel muestra la solución a esto. El punto clave es que la firma general de una función es 'f (* list_args, ** keyword_args)' (no 'f (* list_args)'). – EOL

179

Agregando a cargo desenrolla:

Puede enviar varios argumentos de valores clave también.

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 

Y usted puede mezclar los dos:

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 

ambos deben ser declarados y llamados en ese orden, que es la firma de la función tiene que ser args *, ** kwargs, y llamó ese orden

+2

No estoy seguro de cómo funcionó myfunc (abc = 123, def = 456), pero en el mío (2.7), 'def' no se puede pasar en esta función sin obtener un SyntaxError. Supongo que esto es porque def tiene un significado en python. Pruebe myfunc (abc = 123, fgh = 567) en su lugar. (De lo contrario, excelente respuesta y gracias por ello!) – Dannid

+0

@Dannid: No tengo idea, jaja ... tampoco funciona en 2.6 o 3.2. Lo cambiaré de nombre. – Skurmedel

+0

Cuando dice 'llamado en ese orden', ¿quiere decir aprobado en ese orden? ¿O algo mas? –

11

Agregando a las otras publicaciones excelentes.

A veces no desea especificar el número de argumentos y desea utilizar claves para ellos (el compilador se quejará si un argumento pasado en un diccionario no se utiliza en el método).

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 

A continuación, puede hacer cosas como

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'}) 
____________ 

el código anterior producirá la salida

None None None 
20 None 30 
20 red 30 

Esto es tan bueno como el paso de argumentos variables por medio de un diccionario

+3

Este es un código terrible. Mucho mejor sería: 'f = lambda ** dic: '' .join (dic.get (clave, 'None') para la clave en 'abc')' – metaperture

7

Si se me permite, c de Skurmedel ode es para python 2; para adaptarlo a python 3, cambie iteritems a items y agregue paréntesis a print. Eso podría evitar que principiantes como yo se topen con: AttributeError: 'dict' object has no attribute 'iteritems' y buscar en otro lugar (por ejemplo, Error “ 'dict' object has no attribute 'iteritems' ” when trying to use NetworkX's write_shp()) por qué está sucediendo esto.

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

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

y:

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 
Cuestiones relacionadas