Para conocer lo básico sobre los argumentos de las funciones, consulta el concepto de función.
Los nombres de los parámetros, al igual que los nombres de las variables, deben empezar por una letra o un guion bajo y pueden contener letras, guiones bajos o números. Los nombres de los parámetros no deben contener espacios ni signos de puntuación.
Los argumentos posicionales son valores que se pasan a una función en el mismo orden que los parámetros a los que se vinculan. Opcionalmente, los argumentos posicionales se pueden pasar usando el nombre de su parámetro:
def concat(greeting, name):
return f"{greeting}{name}"
# Passing data to the function by position.
print(concat("Hello, ", "Lilly"))
#-> Hello, Lilly
# Passing data to the function using the parameter name.
print(concat(name="Glenn", greeting="Hello, "))
#-> Hello, Glenn
La primera llamada a concat pasa los argumentos por posición.
La segunda llamada a concat pasa los argumentos por nombre, lo que permite cambiar sus posiciones.
Ten en cuenta que los argumentos posicionales no pueden ir después de argumentos pasados por nombre (también llamados argumentos de palabra clave. No deben confundirse con los parámetros var-posicionales ni con **kwargs).
Este conjunto de argumentos:
print(concat(greeting="Hello, ", "Gregor"))
Da lugar a este error:
SyntaxError: positional argument follows keyword argument
Se pueden exigir argumentos solo posicionales en las llamadas a funciones mediante el uso del operador / en la lista de parámetros:
# Parameters showing a position-only operator.
def concat(greeting, name, /):
return f"{greeting}{name}"
print(concat("Hello, ", "Ginnie"))
#-> Hello, Ginnie
# Call to the function using keyword arguments.
print(concat(name="Franklin", greeting="Hello, "))
Traceback (most recent call last):
print(concat(name="Franklin", greeting="Hello, "))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'
Los argumentos de palabra clave usan el nombre del parámetro al llamar a una función. Opcionalmente, se pueden indicar por posición:
def concat(greeting, name):
return f"{greeting}{name}"
# Function call using parameter names as argument keywords.
print(concat(name="Eliza", greeting="Hello, "))
#-> Hello, Eliza
# Function call with positional data as arguments.
print(concat("Hello, ", "Tim"))
#-> Hello, Tim
Se pueden exigir argumentos solo de palabra clave en las llamadas a funciones mediante el uso del operador * en la lista de parámetros:
# Function definition requiring keyword-only arguments.
def concat(*, greeting, name):
return f"{greeting}{name}"
# Keyword arguments can be in an arbitrary order.
print(concat(name="Kimmie", greeting="Hello, "))
#-> Hello, Kimmie
# Calling the function with positional data raises an error.
print(concat("Hello, ", "Coleen"))
Traceback (most recent call last):
print(concat("Hello, ", "Coleen"))
TypeError: concat() takes 0 positional arguments but 2 were given
Se pueden proporcionar valores predeterminados para uno o varios argumentos en la lista de parámetros. Esto permite llamar a la función con menos argumentos si es necesario. Los valores predeterminados se pueden sobrescribir llamando a la función con un nuevo valor de argumento que reemplace el valor predeterminado:
# Function with default argument values.
def concat(greeting, name="you", punctuation="!"):
return f"{greeting}, {name}{punctuation}"
print(concat("Hello"))
#-> Hello, you!
# Overriding the default values
print(concat("Hello", name="Polly", punctuation="."))
#-> Hello, Polly.
Los argumentos pueden ser posicionales o de palabra clave si no se usan los operadores / ni * en las definiciones de los parámetros.
Como alternativa, los argumentos posicionales o de palabra clave se pueden colocar entre los parámetros solo posicionales de la izquierda y los parámetros solo de palabra clave de la derecha:
# Position-only argument followed by position-or-keyword, followed by keyword-only.
def concat(greeting, /, name, *, ending):
return f"{greeting}{name}{ending}"
print(concat("Hello, ", "Mark", ending="!"))
#-> Hello, Mark!
print(concat("Hello, ", name="Rachel", ending="!"))
#-> Hello, Rachel!
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
Traceback (most recent call last):
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
*argsA menudo, los ejemplos de código usan una definición de función parecida a la siguiente:
def my_function(*args, **kwargs):
# code snipped
*args es un nombre de dos partes que representa una tuple con un número indefinido de argumentos posicionales separados, también conocida como variadic argument.
args es el nombre que se le da a la tuple de argumentos, pero podría ser cualquier otro nombre válido en Python, como my_args, arguments, etc.
El * es el operador que transforma el grupo de argumentos separados en una tuple.
Si alguna vez has desempaquetado una tupla, puede que el * de *args te resulte confuso.
El * en la definición de un parámetro, en lugar de desempaquetar una tupla, convierte uno o varios argumentos posicionales en una tupla.
Decimos que el operador * está sobrecargado, ya que tiene un comportamiento distinto en contextos distintos.
Por ejemplo, * se usa para multiplicar, se usa para desempaquetar y se usa para definir un número arbitrario de parámetros posicionales.
Como una tuple se puede recorrer, args se puede pasar a cualquier otra función que acepte un iterable.
Aunque *args se suele yuxtaponer con **kwargs, no tiene por qué ser así:
def add(*args):
# args is passed to the sum function, which iterates over it.
return sum(args)
print(add(1, 2, 3))
#-> 6
Si *args va después de uno o varios argumentos posicionales, entonces *args será lo que quede después de esos argumentos posicionales:
def add(first, *args):
# first will be 1, leaving the values 2 and 3 in *args
return first + sum(args)
print(add(1, 2, 3))
#-> 6
Si se define uno o varios argumentos predeterminados después de *args, son independientes de los valores de *args:
def add(first, *args, last=0):
return first + sum(args) + last
print(add(1, 2, 3))
#-> 6
print(add(1, 2, 3, last=4))
#-> 10
# This uses the unpacking operator * to separate the list elements into positional arguments.
# It does not have the same behavior as the * (packing) in *args.
print(add(*[1, 2, 3]))
#-> 6
Ten en cuenta que, cuando un argumento ya está dentro de un iterable (como una tuple o una list), hay que desempaquetarlo antes de pasarlo a una función que acepte un número arbitrario de argumentos separados.
Esto se consigue usando *, que es el operador de desempaquetado.
En este contexto, * desempaqueta el contenedor en sus elementos separados, que luego *args transforma en una tuple.
Cuando solo hay argumentos posicionales, la acción de desempaquetar debe dar como resultado el mismo número de argumentos que parámetros formales definidos.
Si no se desempaqueta la lista que se pasa a add, el programa daría un error:
def add(first, *args, last=0):
return first + sum(args) + last
print(add([1, 2, 3]))
Traceback (most recent call last):
print(add([1, 2, 3]))
return first + sum(args) + last
TypeError: can only concatenate list (not "int") to list
**kwargs**kwargs es un nombre de dos partes que representa un número indefinido de argumentos de pares clave-valor.
kwargs es el nombre del grupo de argumentos y podría ser cualquier otro nombre, como my_args, arguments, etc.
El ** transforma el grupo de argumentos con nombre en un dictionary de pares {argument name: argument value}.
Como un diccionario se puede recorrer, kwargs se puede pasar a cualquier otra función que acepte un iterable.
Aunque **kwargs se suele yuxtaponer con *args, no tiene por qué ser así:
def add(**kwargs):
return sum(kwargs.values())
print(add(one=1, two=2, three=3))
#-> 6
Ten en cuenta que se llama al método dict.values() para recorrer los values del diccionario kwargs.
Cuando se recorre un diccionario, lo predeterminado es recorrer sus keys, así que hay que especificar dict.values() de forma explícita:
def concat(**kwargs):
# Join concatenates the tuples from `kwargs.items()`
return " ".join((str(item) for item in kwargs.items()))
print(concat(one=1, two=2, three=3))
#-> ('one', 1) ('two', 2) ('three', 3)