opcionales funciones explicacion argumentos python

python - funciones - ¿Qué significan*args y** kwargs?



kwargs python 3 (5)

¿Qué significan exactamente *args y **kwargs ?

Según la documentación de Python, por lo que parece, pasa en una tupla de argumentos.

def foo(hello, *args): print hello for each in args: print each if __name__ == ''__main__'': foo("LOVE", ["lol", "lololol"])

Esto imprime:

LOVE [''lol'', ''lololol'']

¿Cómo los usas efectivamente?


Además, los usamos para gestionar la herencia.

class Super( object ): def __init__( self, this, that ): self.this = this self.that = that class Sub( Super ): def __init__( self, myStuff, *args, **kw ): super( Sub, self ).__init__( *args, **kw ) self.myStuff= myStuff x= Super( 2.7, 3.1 ) y= Sub( "green", 7, 6 )

De esta manera, Sub no sabe realmente (o le importa) qué es la inicialización de la superclase. Si se da cuenta de que necesita cambiar la superclase, puede arreglar las cosas sin tener que sudar los detalles en cada subclase.


Observe lo bueno en el comentario de S.Lott : también puede llamar a las funciones con *mylist y **mydict para desempaquetar los argumentos posicionales y de palabras clave:

def foo(a, b, c, d): print a, b, c, d l = [0, 1] d = {"d":3, "c":2} foo(*l, **d)

Se imprimirá: 0 1 2 3


Otro buen uso para *args y **kwargs : puede definir funciones genéricas de "captura de todos", lo cual es ideal para decoradores a los que devuelve una envoltura de este tipo en lugar de la función original.

Un ejemplo con un decorador de almacenamiento en caché trivial:

import pickle, functools def cache(f): _cache = {} def wrapper(*args, **kwargs): key = pickle.dumps((args, kwargs)) if key not in _cache: _cache[key] = f(*args, **kwargs) # call the wrapped function, save in cache return _cache[key] # read value from cache functools.update_wrapper(wrapper, f) # update wrapper''s metadata return wrapper import time @cache def foo(n): time.sleep(2) return n*2 foo(10) # first call with parameter 10, sleeps foo(10) # returns immediately


Poner *args y / o **kwargs como los últimos elementos en la lista de argumentos de su definición de función permite que la función acepte un número arbitrario de argumentos y / o argumentos de palabras clave.

Por ejemplo, si desea escribir una función que devuelva la suma de todos sus argumentos, no importa cuántos suministre, podría escribirla así:

def my_sum(*args): return sum(args)

Es probable que se use más comúnmente en la programación orientada a objetos, cuando está anulando una función y desea llamar a la función original con cualquier argumento que el usuario transmita.

No tienes que llamarlos args y kwargs , eso es solo una convención. Son los * y ** que hacen la magia.

La documentación oficial de Python tiene una mirada más profunda .


Solo para aclarar cómo descomprimir los argumentos y cuidar los argumentos faltantes, etc.

def func(**keyword_args): #-->keyword_args is a dictionary print ''func:'' print keyword_args if keyword_args.has_key(''b''): print keyword_args[''b''] if keyword_args.has_key(''c''): print keyword_args[''c''] def func2(*positional_args): #-->positional_args is a tuple print ''func2:'' print positional_args if len(positional_args) > 1: print positional_args[1] def func3(*positional_args, **keyword_args): #It is an error to switch the order ie. def func3(**keyword_args, *positional_args): print ''func3:'' print positional_args print keyword_args func(a=''apple'',b=''banana'') func(c=''candle'') func2(''apple'',''banana'')#It is an error to do func2(a=''apple'',b=''banana'') func3(''apple'',''banana'',a=''apple'',b=''banana'') func3(''apple'',b=''banana'')#It is an error to do func3(b=''banana'',''apple'')