Depuración de decoradores en Python

Los decoradores en Python son realmente una característica muy poderosa. Si es un desarrollador web y ha utilizado el marco Django o incluso algunos otros marcos de desarrollo, ya se habrá encontrado con decoradores.

Para una descripción general, los decoradores son funciones contenedoras que envuelven una función existente o un método y modifican sus características. Tomemos un breve ejemplo. Considere que tiene una función de voz que devuelve un mensaje neutral

Python3

def speak():
    """Returns a neutral message"""
    return "Hi, Geeks!"
  
# printing the output
print(speak())

Producción:

Hi, Geeks!

Suponga que necesita modificar la función para devolver un mensaje en un tono alegre. Así que vamos a crear un decorador para esto.

Python3

# decorator
def make_geek_happy(func):
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
#using the decorator 
@make_geek_happy
def speak():
    """Returns a neutral message"""
    return "Hi, Geeks!"
  
print(speak())

Producción:

Hi, Geeks! You are happy!

Depuración de un decorador

De esta forma, los decoradores también se pueden utilizar para modificar diferentes funciones y hacerlas más útiles. Sin embargo, existen algunos inconvenientes en este proceso. Cuando envolvemos la función original en un decorador, los metadatos de la función original se pierden. Considere el siguiente programa, pero esta vez usamos el decorador de otra manera solo para que lo entienda.

Si intenta acceder a cualquiera de los metadatos de la función positive_message, en realidad devuelve los metadatos del envoltorio dentro del decorador. 

Python3

# decorator
def make_geek_happy(func):
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
def speak():
    """Returns a neutral message"""
    return "Hi!"
  
  
# wrapping the function in the decorator
# and assigning it to positive_message
positive_message = make_geek_happy(speak)
  
print(positive_message())
  
print(speak.__name__) 
print(speak.__doc__) 
print(positive_message.__name__)
print(positive_message.__doc__)

Producción:

Hi! You are happy!
speak
Returns a neutral message
wrapper
None

Estos resultados hacen que sea realmente muy difícil para la depuración. Pero gracias a Python también tiene una solución para arreglar este problema sin mucho esfuerzo. Solo necesitamos usar el decorador functools.wraps() incluido en la biblioteca estándar de Python.

Aquí hay un ejemplo:

Python3

# importing the module
import functools
  
# decorator
def make_geek_happy(func):
    @functools.wraps(func)
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
def speak():
    """Returns a neutral message"""
    return "Hi!"
  
positive_message = make_geek_happy(speak)
print(positive_message())
  
print(speak.__name__) 
print(speak.__doc__) 
print(positive_message.__name__)
print(positive_message.__doc__)

Producción:

Hi! You are happy!
speak
Returns a neutral message
speak
Returns a neutral message

Publicación traducida automáticamente

Artículo escrito por haridarshanc y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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