2012-03-26 17 views
47

en Python, puedo definir una función de la siguiente manera:Llamar a una función de Python con args *, ** y kwargs opcional/por defecto argumentos

def func(kw1=None,kw2=None,**kwargs): 
    ... 

En este caso, puedo llamar a func como:

func(kw1=3,kw2=4,who_knows_if_this_will_be_used=7,more_kwargs=Ellipsis) 

I también puede definir una función como:

def func(arg1,arg2,*args): 
    ... 

que puede ser llamado como

func(3,4,additional,arguments,go,here,Ellipsis) 

Por último, puedo combinar las dos formas

def func(arg1,arg2,*args,**kwargs): 
    ... 

Pero, lo que no funciona está llamando:

func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #SYNTAX ERROR (in python 2 only, apparently this works in python 3) 
    ... 

Mi idea original era que esto era probablemente debido a una función

def func(arg1,arg2,*args,kw1=None): 
    ... 

se puede llamar como

func(1,2,3) #kw1 will be assigned 3 

Así que esto introduciría cierta ambigüedad en cuanto a si 3 deben ser empacados en args o kwargs. Sin embargo, con el pitón 3, existe la posibilidad de especificar la palabra clave únicos argumentos:

def func(a,b,*,kw=None): #can be called as func(1,2), func(1,2,kw=3), but NOT func(1,2,3) 
    ... 

Con esto, parece que no hay ambigüedad sintáctica con:

def func(a,b,*args,*,kw1=None,**kwargs): 
    ... 

Sin embargo, esto todavía aparece una error de sintaxis (probado con Python3.2). ¿Hay alguna razón para esto que me estoy perdiendo? Y, ¿hay alguna manera de obtener el comportamiento que describí anteriormente (Tener * args con argumentos predeterminados)? Sé que puedo simular ese comportamiento manipulando el diccionario kwargs dentro de la función.

+0

no tengo idea de por qué tienes un error de sintaxis para "def func (arg1, arg2, * args, kw1 = None, kw2 = None, ** kwargs):" – okm

+1

@okm Porque no probé esa versión en python 3 , solo Python 2. Simplemente asumí que la versión final funcionaría, y cuando no lo hizo, asumí que las versiones anteriores tampoco funcionarían. ¡Gracias!. – mgilson

+0

¿Cómo debería un '3' desnudo meterse en' kwargs'? ¿Qué palabra clave usaría? No puedo ver ninguna ambigüedad. Tenga en cuenta que el '' 'desnudo en la lista de argumentos solo es útil si no hay' * args'. Es un marcador de posición que usa * en su lugar * de '* args'. –

Respuesta

46

Usted puede hacer eso en Python 3.

def func(a,b,*args,kw1=None,**kwargs): 

El desnudo * sólo se utiliza cuando se desea especificar la palabra clave únicos argumentos sin aceptar un número variable de argumentos posicionales con *args. No usa dos * s.

Para citar de la gramática, en Python 2, tiene

parameter_list ::= (defparameter ",")* 
        ( "*" identifier [, "**" identifier] 
        | "**" identifier 
        | defparameter [","]) 

mientras que en Python 3, tiene

parameter_list ::= (defparameter ",")* 
        ( "*" [parameter] ("," defparameter)* 
        [, "**" parameter] 
        | "**" parameter 
        | defparameter [","]) 

que incluye una disposición para parámetros adicionales después del parámetro *.

4

Si desea hacer una mezcla de ambos recuerde que * args y ** kwargs deben ser los últimos parámetros especificados.

def func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #Invalid 
def func(arg1,arg2,kw1=None,kw2=None,*args,**kwargs): #Valid 

Los comentarios parecen estar basadas en la mezcla hasta cómo se construye una definición de función en comparación con cómo los argumentos presentados se asignan de nuevo a los parámetros especificados en la definición.

Esta es la definición de esta función que tiene 6 parámetros. Se llama al pasarle argumentos con nombre y sin nombre en una llamada a función.

Para este ejemplo ... Cuando se llama un argumento al llamar a la función, se puede proporcionar desordenado. arg1 y arg2 son parámetros obligatorios y si no se pasan a la función como argumentos con nombre, entonces deben asignarse en orden a partir de los argumentos proporcionados sin nombre. kw1 y kw2 tienen valores predeterminados proporcionados en la definición de la función, por lo que no son obligatorios, pero si no se proporcionan como argumentos con nombre, tomarán cualquier valor disponible de los argumentos proporcionados restantes no proporcionados. Cualquier argumento sin nombre sobrante se proporciona a la función en una matriz llamada args Cualquier argumento con nombre que no tenga un nombre de parámetro correspondiente en la definición de función se proporciona a la llamada de función en un diccionario llamado kwargs.

+5

Esto es sintácticamente válido, pero no funciona como uno podría esperar porque hay ambigüedad en cuanto a si los argumentos requeridos adicionales se asignan a los argumentos de palabra clave o * args. – tonycpsu

+2

Daría un paso más y diría que esto no funciona para hacer kw1 y kw2 'keyword' args con Python 2.7, ¡por eso estoy aquí! La forma se enumeraría mejor como 'func (arg1, arg2, arg3 = None, arg4 = None, * args, ** kwargs): #Valid con los valores predeterminados en args posicionales', pero esto es realmente solo cuatro args posicionales, dos de que son opcionales Para pasar kwargs, deberás completar * los cuatro argumentos *, incluidos arg3 y arg4. – sage

+2

Sugiero http://stackoverflow.com/a/15302038/527489 para Python 2.7 y observe el 'def_val'. – sage

Cuestiones relacionadas