Python Language Definiendo una función con un número arbitrario de argumentos.


Ejemplo

Número arbitrario de argumentos posicionales:

La definición de una función capaz de tomar un número arbitrario de argumentos se puede hacer prefijando uno de los argumentos con un *

def func(*args):
    # args will be a tuple containing all values that are passed in
    for i in args:
        print(i)

func(1, 2, 3)  # Calling it with 3 arguments
# Out: 1
#      2
#      3

list_of_arg_values = [1, 2, 3]
func(*list_of_arg_values)  # Calling it with list of values, * expands the list
# Out: 1
#      2
#      3 

func()  # Calling it without arguments
# No Output 

No puede proporcionar un valor predeterminado para args , por ejemplo func(*args=[1, 2, 3]) generará un error de sintaxis (ni siquiera compilará).

No puede proporcionarlos por nombre al llamar a la función, por ejemplo, func(*args=[1, 2, 3]) generará un TypeError .

Pero si ya tiene sus argumentos en una matriz (o cualquier otro Iterable ), puede invocar su función así: func(*my_stuff) .

Se puede acceder a estos argumentos ( *args ) por índice, por ejemplo, args[0] devolverá el primer argumento

Número arbitrario de argumentos de palabras clave

Puede tomar un número arbitrario de argumentos con un nombre definiendo un argumento en la definición con dos * delante:

def func(**kwargs):
    # kwargs will be a dictionary containing the names as keys and the values as values
    for name, value in kwargs.items():
        print(name, value)

func(value1=1, value2=2, value3=3)   # Calling it with 3 arguments
# Out: value1 1
#      value2 2
#      value3 3

func()                               # Calling it without arguments
# No Out put

my_dict = {'foo': 1, 'bar': 2}
func(**my_dict)                      # Calling it with a dictionary
# Out: foo 1
#      bar 2

No puede proporcionarlos sin nombres, por ejemplo, func(1, 2, 3) generará un TypeError .

kwargs es un simple diccionario nativo de python. Por ejemplo, args['value1'] dará el valor para el argumento value1 . Asegúrese de verificar de antemano que exista tal argumento o se KeyError un KeyError .

Advertencia

Puede combinar estos con otros argumentos opcionales y requeridos, pero el orden dentro de la definición es importante.

Los argumentos posicionales / palabras clave son lo primero. (Argumentos requeridos).
Luego vienen los argumentos arbitrarios *arg . (Opcional).
Luego vienen los argumentos de palabra clave . (Necesario).
Finalmente la palabra clave arbitraria **kwargs viene. (Opcional).

#       |-positional-|-optional-|---keyword-only--|-optional-|
def func(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs):
     pass
  • arg1 debe darse, de lo contrario se TypeError un TypeError . Se puede dar como argumento posicional ( func(10) ) o de palabra clave ( func(arg1=10) ).
  • kwarg1 debe proporcionar kwarg1 , pero solo se puede proporcionar como palabra clave-argumento: func(kwarg1=10) .
  • arg2 y kwarg2 son opcionales. Si se va a cambiar el valor, se aplican las mismas reglas que para arg1 (posicional o palabra clave) y kwarg1 (solo palabra clave).
  • *args captura parámetros posicionales adicionales. Pero tenga en cuenta que arg1 y arg2 deben proporcionarse como argumentos posicionales para pasar argumentos a *args : func(1, 1, 1, 1) .
  • **kwargs captura todos los parámetros de palabras clave adicionales. En este caso, cualquier parámetro que no sea arg1 , arg2 , kwarg1 o kwarg2 . Por ejemplo: func(kwarg3=10) .
  • En Python 3, puede usar * solo para indicar que todos los argumentos posteriores deben especificarse como palabras clave. Por ejemplo, la función math.isclose en Python 3.5 y superior se define usando def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , lo que significa que los primeros dos argumentos se pueden suministrar de manera posicional pero el opcional Los parámetros tercero y cuarto solo se pueden suministrar como argumentos de palabras clave.

Python 2.x no admite parámetros de palabras clave solamente. Este comportamiento puede ser emulado con kwargs :

def func(arg1, arg2=10, **kwargs):
    try:
        kwarg1 = kwargs.pop("kwarg1")
    except KeyError:
        raise TypeError("missing required keyword-only argument: 'kwarg1'")

    kwarg2 = kwargs.pop("kwarg2", 2)
    # function body ...

Nota sobre nombrar

La convención de nombrar argumentos opcionales posicionales args y opcionales de palabras clave kwargs es solo una convención que puede usar cualquier nombre que desee, pero es útil seguir la convención para que otros sepan lo que está haciendo, o incluso usted mismo más adelante, así que hágalo.

Nota sobre la singularidad

Cualquier función se puede definir con ninguno o un *args y ninguno o uno **kwargs pero no con más de uno de cada uno. También *args debe ser el último argumento posicional y **kwargs debe ser el último parámetro. El intento de utilizar más de uno de ambos dará lugar a una excepción de error de sintaxis.

Nota sobre funciones de anidamiento con argumentos opcionales

Es posible anidar dichas funciones y la convención habitual es eliminar los elementos que el código ya ha manejado, pero si está pasando los parámetros, debe pasar argumentos opcionales posicionales con un prefijo * y argumentos de palabras clave opcionales con un prefijo ** , de lo contrario, los argumentos se pueden pasar como una lista o tupla y los kwargs como un solo diccionario. p.ej:

def fn(**kwargs):
    print(kwargs)
    f1(**kwargs)

def f1(**kwargs):
    print(len(kwargs))

fn(a=1, b=2)
# Out:
# {'a': 1, 'b': 2}
# 2