propias - lista de funciones de python
Llamar a una funciĆ³n de Python con*args,** kwargs y argumentos opcionales/predeterminados (2)
Puedes hacer eso en Python 3.
def func(a,b,*args,kw1=None,**kwargs):
El bare *
solo se usa cuando desea especificar argumentos de palabra clave sin aceptar una cantidad variable de argumentos posicionales con *args
. No usas dos *
s.
Para citar la gramática, en Python 2, tienes
parameter_list ::= (defparameter ",")*
( "*" identifier [, "**" identifier]
| "**" identifier
| defparameter [","] )
mientras que en Python 3, tienes
parameter_list ::= (defparameter ",")*
( "*" [parameter] ("," defparameter)*
[, "**" parameter]
| "**" parameter
| defparameter [","] )
que incluye una provisión para parámetros adicionales después del parámetro *
.
En python, puedo definir una función de la siguiente manera:
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)
También puedo definir una función como:
def func(arg1,arg2,*args):
...
que se puede llamar como
func(3,4,additional,arguments,go,here,Ellipsis)
Finalmente, puedo combinar las dos formas
def func(arg1,arg2,*args,**kwargs):
...
Pero, lo que no funciona es llamar:
func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #SYNTAX ERROR (in python 2 only, apparently this works in python 3)
...
Mi pensamiento original fue que esto fue probablemente porque una función
def func(arg1,arg2,*args,kw1=None):
...
puede ser llamado como
func(1,2,3) #kw1 will be assigned 3
Por lo tanto, esto introduciría cierta ambigüedad en cuanto a si 3 se debe empaquetar en args o kwargs. Sin embargo, con python 3, existe la posibilidad de especificar argumentos solo de palabra clave:
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 aún provoca un 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.
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 basarse en mezclar cómo se construye una definición de función en comparación con cómo los argumentos proporcionados se asignan 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 nombra un argumento cuando se llama 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 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. Los argumentos no nombrados restantes se proporcionan a la función en una matriz denominada args. Todos los argumentos con nombre que no tienen un nombre de parámetro correspondiente en la definición de la función se proporcionan a la llamada de función en un diccionario llamado kwargs.