Introducción a Python Functools

Hola habrovsk Hemos preparado una traducción de otro material útil antes del inicio del curso Python Developer .




Python es un lenguaje de programación orientado a objetos de alto nivel. Una de las mayores ventajas de Python es que tiene una funcionalidad especial que le permite escribir código reutilizable utilizando las herramientas de lenguaje incorporadas.

Functools es una biblioteca de Python diseñada para trabajar con funciones de orden superior. Dichas funciones pueden tomar otras funciones y devolver funciones. Ayudan al desarrollador a escribir código que pueda reutilizarse. Las funciones se pueden usar o ampliar sin reescribirlas por completo. El módulo functools en Python proporciona varias herramientas que le permiten lograr el efecto descrito. Por ejemplo, lo siguiente:

  • Parcial
  • Pedidos completos;
  • update_wrapperpara parcial .

La función parcial es una de las principales herramientas proporcionadas por functools . Vamos a resolverlo con ejemplos.

Característica parcial en Python


En el módulo functools , la función parcial se considera una de las herramientas más importantes. Usando una función parcial , puede reemplazar una función existente que ya ha pasado argumentos. Además, también podemos crear una nueva versión de la función agregando documentación de calidad.

Podemos crear nuevas funciones pasando argumentos parciales. También podemos congelar algunos argumentos de función, lo que conducirá a la aparición de un nuevo objeto. Otra forma de representar parcial , es que con su ayuda podemos crear una función con valores predeterminados. Parcial admite palabras clave y argumentos posicionales como fijos.
Veamos ejemplos.

¿Cómo crear una función parcial ?


Para crear una función parcial , use functoolspartial() de la biblioteca . Está escrito de la siguiente manera:

partial(func, /, *args, ** kwargs)

Entonces crea una función parcial que llama a func , pasándole palabras clave fijas y argumentos posicionales. Aquí, generalmente se pasan algunos argumentos necesarios para llamar a la función func . Los argumentos restantes se pasan en * args y ** kwargs .

Supongamos que la siguiente función agrega dos números:

def multiply(x, y):
 
    return x * y

Ahora considere el caso cuando necesitábamos duplicar o triplicar un número dado. En este caso, definimos nuevas funciones como se muestra a continuación:

def multiply(x, y):
        return x * y
 
def doubleNum(x):
       return multiply(x, 2)
 
def tripleNum(x):
       return multiply(x, 3)

Cuando el script de la función es solo 2-3, por supuesto, es más lógico hacerlo, como se muestra arriba. Pero cuando necesita escribir otras 100 funciones, entonces no tiene sentido reescribir el mismo código tantas veces. Aquí es donde las funciones parciales son útiles . Para usarlos, primero, necesitamos importar parciales de Functools .

from functools import partial
 
def multiply(x, y):
       return x * y
 
doubleNum = partial(multiply, 2)
   tripleNum = partial(multiply, 3)
 
Print(doubleNum(10))
 
Output: 20

Como puede ver en el ejemplo, los valores predeterminados serán reemplazados por las variables de la izquierda. En lugar de x habrá 2, y en lugar de y habrá 10 al llamar a doubleNum (10) . En este ejemplo, el orden no importará, pero en otros usos, puede importar. Veamos un ejemplo para este caso para comprender el orden de sustitución de variables.

from functools import partial
def orderFunc(a,b,c,d):
      return a*4 + b*3 + c*2 + d
 
result = partial(orderFunc,5,6,7)
print(result(8))
 
Output: 60

Pedido completo


Tenemos una función orderFunc()en la que multiplicamos apor 4, bpor 3, cpor 2 y agregamos dvalores a la suma.

Hemos creado una función parcialresult() que llama orderFunc()con los valores 5, 6 y 7. Ahora los valores 5, 6 y 7 reemplazarán las variables a, by en cconsecuencia. La variable dserá reemplazada por 8, ya que se transmite cuando se llama result(). El resultado es (4 * 5 + 6 * 3 + 7 * 2 + 8) = 60.

En este caso, el orden de los valores transmitidos será importante, porque si el orden cambia, el resultado también cambiará. Para corregir variables, puede usar palabras clave en lugar de argumentos posicionales. Reescribamos el código anterior usando palabras clave como argumentos.

from functools import partial
def orderFunc(a,b,c,d):
       return a*4 + b*3 + c*2 + d
 
 result = partial(orderFunc,c=5,d=6)
print(result(8,4))
 
Output: 60

Aquí fijamos el valor 5 para la variable cy 6 para la variable d. En lugar de variables a, baparecerán valores de 8 y 4. Como resultado, obtenemos (8 * 4 + 4 * 3 + 5 * 2 + 6) = 60.

La función parcial puede determinarse en un bucle y usarse para cálculos repetidos. Veamos un ejemplo:

from functools import partial
 
def add(x,y):
      return x + y
 
add_partials = []
for i in range (1, 10):
      function = partial(add, i)
      add_partials.append(function)
      print('Sum of {} and 2 is {}'.format(i,add_partials[i-1](2)))
 
  
Output:
 
Sum of 1 and 2 is 3
Sum of 2 and 2 is 4
Sum of 3 and 2 is 5
Sum of 4 and 2 is 6
Sum of 5 and 2 is 7
Sum of 6 and 2 is 8
Sum of 7 and 2 is 9
Sum of 8 and 2 is 10
Sum of 9 and 2 is 11

En este ejemplo, resumiremos un cierto rango de valores con 2, reutilizando la función existente. Podemos llamar a parcial en el ciclo y usar su funcionalidad para calcular las sumas. Como se puede ver en los valores en la salida, tenemos un ciclo de 1 a 10 y todos los valores en este intervalo se suman a 2 usando la función parcial , que llama a la función de suma.

Metadatos


Aunque las funciones parciales son independientes, retienen la memoria (metadatos) de una función que extienden.

from functools import partial
 
def add(x,y):
      return x + y
 
# create a new function that multiplies by 2
result = partial(add,y=5)
print(result.func)
print(result.keywords)
 
Output:
<function add at 0x7f27b1aab620>
{'y': 5}

La primera llamada a func pasará el nombre de la función y su dirección en la memoria, y la segunda llamada con palabras clave pasará las palabras clave a la función. Por lo tanto, las funciones parciales pueden llamarse autodocumentadas utilizando metadatos que reciben de una función extensible. Podemos actualizar metadatos de funciones usando otra herramienta de functools . Es una herramienta que puede usar para actualizar metadatos de características. Vamos a resolverlo con un ejemplo.

update_wrapper partial

Update_wrapper

def multiply(x, y):
 
    """Test string."""
 
    return x * y
 
 result = functools.partial(multiply, y=2)
 
 try:
 
    print ('Function Name:'+result.__name__)
 
except AttributeError:
 
    print('Function Name: __no name__')
 
 print ('Function Doc:'+result.__doc__)
 
 print('Updating wrapper:')
 
functools.update_wrapper(result, multiply)
 
 print ('Function Name:'+result.__name__)
 
print ('Function Doc:'+result.__doc__)
 
Output:
 
Function Name: __no name__
 
Function Doc:partial(func, *args, **keywords) - new function with partial application
 
    of the given arguments and keywords.
 
 
Updating wrapper:
 
Function Name: multiply
Function Doc: Test string.

Ahora, como puede ver en la salida, antes de usar el contenedor, la función no tenía un nombre o documento asignado. Tan pronto como actualizamos las funciones de nombre y documento con update_wrapper, vimos el resultado correspondiente en la salida.

Conclusión


Con functools podemos deshacernos del código redundante y aumentar las posibilidades de reutilizar código en Python. Cuanto más a menudo use la función parcial , más casos de uso abrirá. ¡Experimenta y disfruta!



Súbete al curso.



All Articles