Categorías
Python

API burla externos en Python

 

Tabla de Contenidos

  • pasar múltiples parámetros a la función
  • mediante la variable del pitón args en función Definiciones
  • mediante la variable del pitón kwargs en función Definiciones
  • Argumentos de pedido en una función
  • desembalaje con los operadores del asterisco: * Y **
  • Conclusión

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: args y kwargs Python: Desmitificar

A veces, cuando nos fijamos en una definición de función en Python, es posible que vea que toma dos argumentos extraños: * args y ** kwargs . Si alguna vez se preguntó lo que estas variables son peculiares, o por qué su IDE que las define en main (), entonces este artículo es para usted. Vas a aprender cómo utilizar argumentos y kwargs en Python para añadir más flexibilidad para sus funciones.

Al final del artículo, usted sabrá:

  • Lo args * y ** significan realmente kwargs
  • Cómo utilizar * args y ** kwargs en la definición de funciones
  • Cómo utilizar un solo asterisco (*) para desempaquetar iterables
  • Cómo utilizar dos asteriscos (**) a los diccionarios de desempaquetado

Este artículo se supone que ya sabe cómo definir las funciones de Python y el trabajo con las listas y diccionarios. Bono

gratuito: Haga clic aquí para obtener una hoja de trucos Python y aprender los conceptos básicos de Python 3, como trabajar con tipos de datos, diccionarios, listas y funciones de Python.

pasar múltiples parámetros a la función

* args y ** kwargs permite pasar múltiples argumentos o argumentos de palabras clave para una función. Consideremos el siguiente ejemplo. Esta es una función simple que toma dos argumentos y devuelve su suma:

def my_sum(a, b):
return a + b

Esta función funciona bien, pero está limitado a sólo dos argumentos. ¿Qué pasa si necesita sumar un número variable de argumentos, en los que el número específico de argumentos pasados ​​únicamente se determina en tiempo de ejecución? ¿No sería grande para crear una función que podría resumir todas los enteros que se le pasa, no importa cuántos hay?

Uso de la variable args Python en función Definiciones

Hay algunas formas en las que puede pasar un número variable de argumentos a una función. La primera forma es a menudo el más intuitivo para las personas que tienen experiencia con colecciones. Sólo tiene que pasar una lista o un conjunto de todos los argumentos a su función. Así que para my_sum (), usted podría pasar una lista de todos los números enteros que hay que añadir:

# sum_integers_list.py
def my_sum(my_integers):
result = 0
for x in my_integers:
result += x
return result

list_of_integers = [1, 2, 3]
print(my_sum(list_of_integers))

Esta implementación trabajos, pero cada vez que llame a esta función también necesitará para crear una lista de argumentos para transmitir a la misma. Esto puede ser un inconveniente, especialmente si usted no sabe por adelantado todos los valores que deben entrar en la lista.

Aquí es donde * args puede ser muy útil, ya que le permite pasar un número variable de argumentos posicionales. Tomemos el siguiente ejemplo:

# sum_integers_args.py
def my_sum(*args):
result = 0
# Iterating over the Python args tuple
for x in args:
result += x
return result

print(my_sum(1, 2, 3))

En este ejemplo, ya no estás pasando una lista de my_sum (). En su lugar, estás pasando tres argumentos posicionales diferentes. my_sum () toma todos los parámetros que se proporcionan en la entrada y los paquetes de todos ellos en un solo objeto iterable nombre args.

Tenga en cuenta que args es sólo un nombre. Usted no está obligado a utilizar los argumentos de nombre. Se puede elegir cualquier nombre que prefiera, tales como números enteros:

# sum_integers_args_2.py
def my_sum(*integers):
result = 0
for x in integers:
result += x
return result

print(my_sum(1, 2, 3))

La función sigue funcionando, incluso si se pasa el objeto iterable como enteros en lugar de argumentos. Todo lo que importa aquí es que se utiliza el operador de desembalaje (*).

Tenga en cuenta que el objeto iterable obtendrá mediante el operador * desembalaje no es una lista, pero una tupla. Una tupla es similar a una lista en la que ambos rebanar el apoyo y la iteración. Sin embargo, las tuplas son muy diferentes en al menos un aspecto: listas son mutables, mientras tuplas no lo son. Para probar esto, ejecute el código siguiente. Este script intenta cambiar un valor de una lista:

# change_list.py
my_list = [1, 2, 3]
my_list[0] = 9
print(my_list)

El valor se encuentra en el primer índice de la lista debe ser actualizada a 9. Si se ejecuta este script, se verá que la lista de hecho es modificado:

$ python change_list.py
[9, 2, 3]

el primer valor ya no es 0, pero el valor actualizado 9. Ahora, trata de hacer lo mismo con una tupla:

# change_tuple.py
my_tuple = (1, 2, 3)
my_tuple[0] = 9
print(my_tuple)

Aquí, se ven los mismos valores, excepto que están mantienen unidos como una tupla. Si intenta ejecutar esta secuencia de comandos, se verá que el intérprete de Python devuelve un error:

$ python change_tuple.py
Traceback (most recent call last):
File "change_tuple.py", line 3, in
my_tuple[0] = 9
TypeError: 'tuple' object does not support item assignment

Esto se debe a una tupla es un objeto inmutable, y sus valores no se puede cambiar después de la asignación. Tenga esto en cuenta cuando se trabaja con tuplas y * args.

Usando la variable de Python kwargs en función Definiciones

Bien, ahora que has entendido lo que * args es para, pero ¿qué pasa kwargs **? ** kwargs funciona igual que args *, pero en lugar de aceptar los argumentos posicionales que acepta la palabra clave (o nombrados ) argumentos. Tome el ejemplo siguiente:

# concatenate.py
def concatenate(**kwargs):
result = ""
# Iterating over the Python kwargs dictionary
for arg in kwargs.values():
result += arg
return result

print(concatenate(a="Real", b="Python", c="Is", d="Great", e="!"))

Cuando se ejecuta el script anterior, concatenar () se repetirá a través del pitón kwargs diccionario y concatenar todos los valores que encuentra: args

$ python concatenate.py
RealPythonIsGreat!

igual, kwargs es sólo un nombre que puede ser cambiado a cualquier usted quiere. Una vez más, lo que es importante aquí es el uso de la operador de desembalaje (**).

Así, el ejemplo anterior podría escribirse así:

# concatenate_2.py
def concatenate(**words):
result = ""
for arg in words.values():
result += arg
return result

print(concatenate(a="Real", b="Python", c="Is", d="Great", e="!"))

Tenga en cuenta que en el ejemplo anterior el objeto iterable es un diccionario estándar. Si iterar sobre el diccionario y desea volver a sus valores, al igual que en el ejemplo que se muestra, a continuación, debe utilizar .values ​​().

De hecho, si se olvida de utilizar este método, se encontrará iteración a través de las teclas de sus kwargs Python diccionario de lugar, como en el siguiente ejemplo:

# concatenate_keys.py
def concatenate(**kwargs):
result = ""
# Iterating over the keys of the Python kwargs dictionary
for arg in kwargs:
result += arg
return result

print(concatenate(a="Real", b="Python", c="Is", d="Great", e="!"))

Ahora bien, si se intenta ejecutar este ejemplo, notará el siguiente resultado:

$ python concatenate_keys.py
abcde

Como se puede ver, si no se especifica .values ​​(), su función será iterar sobre las claves de su diccionario de Python kwargs, devolviendo el resultado equivocado.

Argumentos de pedido en una función

Ahora que ha aprendido lo que * args y ** kwargs corresponden, ya está listo para empezar a escribir funciones que toman un número variable de argumentos de entrada. Pero lo que si se desea crear una función que toma un número variable de ambos argumentos posicionales y nombre?

En este caso, hay que tener en cuenta que las cuentas de orden . Al igual que los argumentos no predeterminados tienen que preceden los argumentos por defecto, por lo que * args deben venir antes kwargs **.

En resumen, el orden correcto de los parámetros es:

Por ejemplo, esta definición de función es correcta:

# correct_function_definition.py
def my_function(a, b, *args, **kwargs):
pass

La variable * args aparece de forma adecuada antes kwargs **. Pero lo que si se intenta modificar el orden de los argumentos? Por ejemplo, considere la siguiente función:

# wrong_function_definition.py
def my_function(a, b, **kwargs, *args):
pass

Ahora, ** kwargs viene antes args * en la definición de función. Si intenta ejecutar este ejemplo, recibirá un error del intérprete:

$ python wrong_function_definition.py
File "wrong_function_definition.py", line 2
def my_function(a, b, **kwargs, *args):
^
SyntaxError: invalid syntax

En este caso, dado que * args se produce después de kwargs **, el intérprete de Python lanza una SyntaxError.

desembalaje con los operadores del asterisco: * y **

que ahora son capaces de utilizar args * y ** kwargs para definir las funciones de Python que toman un número variable de argumentos de entrada. Vayamos un poco más profundo para entender algo más sobre los operadores desembalaje .

El asterisco simple y doble desembalaje operadores se introdujeron en Python 2. A partir de la versión 3.5, se han vuelto aún más potente, gracias a PEP 448. En resumen, los operadores de desembalaje son operadores que desempaquetar los valores de iterable objetos en Python . El único operador asterisco * puede ser utilizado en cualquier iterable que Python proporciona, mientras que el operador doble asterisco ** sólo se puede utilizar en los diccionarios. inicio de

Vamos con un ejemplo:

# print_list.py
my_list = [1, 2, 3]
print(my_list)

Este código define una lista y luego lo imprime en la salida estándar:

$ python print_list.py
[1, 2, 3]

Nota cómo se imprime la lista, junto con los soportes correspondientes y comas.

Ahora, trate de usar el operador * desembalaje al nombre de su lista:

# print_unpacked_list.py
my_list = [1, 2, 3]
print(*my_list)

En este caso, el operador * dice impresión () para expandir la lista en primer lugar.

En este caso, la salida ya no es la lista en sí, sino más bien el contenido de la lista:

$ python print_unpacked_list.py
1 2 3

¿Puede usted ver la diferencia entre esta realización y la de print_list.py? En lugar de una lista, imprimir () ha tomado tres argumentos separados que la entrada.

Otra cosa que usted notará es que en print_unpacked_list.py, que utilizó el operador desembalaje * llamar a una función, en lugar de en una definición de función. En este caso, la impresión () toma todos los elementos de una lista como si fueran argumentos individuales.

También puede utilizar este método para llamar a sus funciones propias, pero si su función requiere un número específico de argumentos, entonces el iterable desembalar debe tener el mismo número de argumentos.

Para probar este comportamiento, tenga en cuenta este script:

# unpacking_call.py
def my_sum(a, b, c):
print(a + b + c)

my_list = [1, 2, 3]
my_sum(*my_list)

Aquí, my_sum () establece explícitamente que a, b, y c son argumentos necesarios.

Si ejecuta este script, obtendrá la suma de los tres números en my_list:

$ python unpacking_call.py
6

Los 3 elementos en my_list coinciden perfectamente con los argumentos necesarios en my_sum ().

Ahora vistazo a la siguiente secuencia de comandos, donde my_list tiene 4 argumentos en lugar de 3:

# wrong_unpacking_call.py
def my_sum(a, b, c):
print(a + b + c)

my_list = [1, 2, 3, 4]
my_sum(*my_list)

En este ejemplo, my_sum () aún espera sólo tres argumentos, pero el operador * obtiene 4 elementos de la lista. Si intenta ejecutar esta secuencia de comandos, verá que el intérprete de Python no es capaz de ejecutarlo:

$ python wrong_unpacking_call.py
Traceback (most recent call last):
File "wrong_unpacking_call.py", line 6, in
my_sum(*my_list)
TypeError: my_sum() takes 3 positional arguments but 4 were given

Cuando se utiliza el operador * para descomprimir una lista y pasar argumentos a una función, que es exactamente igual que si usted está pasando cada argumento solo. Esto significa que se pueden utilizar múltiples operadores de desembalaje para obtener valores a partir de varias listas y pasarlos todos a una sola función.

Para probar este comportamiento, considere el siguiente ejemplo:

# sum_integers_args_3.py
def my_sum(*args):
result = 0
for x in args:
result += x
return result

list1 = [1, 2, 3]
list2 = [4, 5]
list3 = [6, 7, 8, 9]

print(my_sum(*list1, *list2, *list3))

Si ejecuta este ejemplo, las tres listas son desempaquetado. Cada elemento individual se pasa a my_sum (), resultando en la salida siguiente:

$ python sum_integers_args_3.py
45

Hay otros usos convenientes del operador desembalaje. Por ejemplo, digamos que usted necesita para dividir una lista en tres partes diferentes. La salida debe mostrar el primer valor, el último valor, y todos los valores intermedios. Con el operador de desembalaje, se puede hacer esto en una sola línea de código:

# extract_list_body.py
my_list = [1, 2, 3, 4, 5, 6]

a, *b, c = my_list

print(a)
print(b)
print(c)

En este ejemplo, my_list contiene 6 artículos. La primera variable se asigna a una, el último en c, y todos los demás valores se empaquetan en una lista nueva b. Si ejecuta la secuencia de comandos, print () le mostrará que sus tres variables tienen los valores que se esperan:

$ python extract_list_body.py
1
[2, 3, 4, 5]
6

Otra cosa interesante que puede hacer con el operador * desembalaje es dividir los artículos de cualquier objeto iterable. Esto podría ser muy útil si necesita combinar dos listas, por ejemplo:

# merging_lists.py
my_first_list = [1, 2, 3]
my_second_list = [4, 5, 6]
my_merged_list = [*my_first_list, *my_second_list]

print(my_merged_list)

El operador * desembalaje se antepone a la vez my_first_list y my_second_list.

Si ejecuta este script, verá que el resultado es una lista combinada:

$ python merging_lists.py
[1, 2, 3, 4, 5, 6]

Puede incluso combinar dos diferentes diccionarios usando el operador de desembalaje **:

# merging_dicts.py
my_first_dict = {"A": 1, "B": 2}
my_second_dict = {"C": 3, "D": 4}
my_merged_dict = {**my_first_dict, **my_second_dict}

print(my_merged_dict)

Aquí, los iterables para fusionar son my_first_dict y my_second_dict.

La ejecución de este código genera un fusionaron diccionario:

$ python merging_dicts.py
{'A': 1, 'B': 2, 'C': 3, 'D': 4}

Recuerde que el operador * funciona en cualquier objeto iterable. También se puede utilizar para descomprimir una cadena:

# string_to_list.py
a = [*"RealPython"]
print(a)

En Python, las cadenas son objetos iterables, así * lo descomprimirá y coloque todos los valores individuales en una lista a:

$ python string_to_list.py
['R', 'e', 'a', 'l', 'P', 'y', 't', 'h', 'o', 'n']

El ejemplo anterior parece muy bien, pero cuando se trabaja con estos operadores es importante tener en cuenta la regla séptima del el Zen de Python por Tim Peters: legibilidad cuenta .

Para ver por qué, consideremos el siguiente ejemplo:

# mysterious_statement.py
*a, = "RealPython"
print(a)

Ahí está el operador * desembalaje, seguido por una variable, una coma, y ​​una asignación. Eso es un montón embalado en una sola línea! De hecho, este código no es diferente del ejemplo anterior. Solo se necesita la cadena RealPython y asigna todos los elementos a la nueva lista a, gracias a que el operador de desembalaje *.

La coma después de la una hace el truco. Cuando se utiliza el operador de desempaquetar con la asignación de variables, Python requiere que la variable de resultado es una lista o una tupla. Con la coma final, en realidad se ha definido una tupla con un solo nombre de una variable.

Si bien este es un buen truco, muchos Pythonistas no consideraría este código para ser muy fácil de leer. Por lo tanto, lo mejor es utilizar este tipo de construcciones con moderación.

Conclusión

Ahora puede utilizar * args y ** kwargs a aceptar un número variable de argumentos en sus funciones. También ha aprendido algo más sobre los operadores de desembalaje.

Usted ha aprendido:

  • Lo args * y ** significan realmente kwargs
  • Cómo utilizar * args y ** kwargs en la definición de funciones
  • Cómo utilizar un solo asterisco (*) para desempaquetar iterables
  • Cómo utilizar dos asteriscos (**) a los diccionarios de desempaquetado

Si todavía tiene preguntas, no dude en llegar en la sección de comentarios! Para obtener más información sobre el uso de los asteriscos en Python, echar un vistazo a el artículo de Trey Hunner sobre el tema.

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: args Python y kwargs: Desmitificar

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *