Clase como decorador en python

Los decoradores son una herramienta muy poderosa y útil en Python, ya que permite a los programadores modificar el comportamiento de una función o clase. Los decoradores nos permiten envolver otra función para extender el comportamiento de la función envuelta, sin modificarla permanentemente. 
Podemos definir un decorador como una clase para hacer eso, tenemos que usar un método de clases __call__. Cuando un usuario necesita crear un objeto que actúe como una función, el decorador de funciones debe devolver un objeto que actúe como una función, por lo que __call__ puede ser útil. Por ejemplo 
 

Python3

# Python program showing
# use of __call__() method
 
class MyDecorator:
    def __init__(self, function):
        self.function = function
     
    def __call__(self):
 
        # We can add some code
        # before function call
 
        self.function()
 
        # We can also add some code
        # after function call.
 
 
# adding class decorator to the function
@MyDecorator
def function():
    print("GeeksforGeeks")
 
function()
Producción: 

GeeksforGeeks

 

  
Decorador de clases con *args y **kwargs: 
para usar el decorador de clases con argumentos *args y **kwargs, usamos una función __call__ y pasamos ambos argumentos en una función dada 
 

Python3

# Python program showing
# class decorator with *args
# and **kwargs
 
class MyDecorator:
    def __init__(self, function):
        self.function = function
     
    def __call__(self, *args, **kwargs):
 
        # We can add some code
        # before function call
 
        self.function(*args, **kwargs)
 
        # We can also add some code
        # after function call.
     
 
# adding class decorator to the function
@MyDecorator
def function(name, message ='Hello'):
    print("{}, {}".format(message, name))
 
function("geeks_for_geeks", "hello")
Producción: 

hello, geeks_for_geeks

 

  
Decorador de clase con declaración de devolución: 
en el ejemplo dado, las funciones no devolvieron nada, por lo que no hay ningún problema, pero es posible que necesite el valor devuelto. Entonces usamos declaración de retorno con el decorador de clase. 
 

Python3

# Python program showing
# class decorator with
# return statement
 
class SquareDecorator:
 
    def __init__(self, function):
        self.function = function
 
    def __call__(self, *args, **kwargs):
 
        # before function
        result = self.function(*args, **kwargs)
 
        # after function
        return result
 
 # adding class decorator to the function
@SquareDecorator
def get_square(n):
    print("given number is:", n)
    return n * n
 
print("Square of number is:", get_square(195))
Producción: 

given number is: 195
Square of number is: 38025

 

  
Usando la clase Decorators para imprimir el tiempo requerido para ejecutar un programa: 
para imprimir el tiempo requerido para ejecutar un programa, usamos la función __call__ y usamos un módulo de tiempo para que podamos obtener el tiempo de ejecución de un programa 
 

Python3

# Python program to execute
# time of a program
 
# importing time module
from time import time
class Timer:
 
    def __init__(self, func):
        self.function = func
 
    def __call__(self, *args, **kwargs):
        start_time = time()
        result = self.function(*args, **kwargs)
        end_time = time()
        print("Execution took {} seconds".format(end_time-start_time))
        return result
 
 
# adding a decorator to the function
@Timer
def some_function(delay):
    from time import sleep
 
    # Introducing some time delay to
    # simulate a time taking function.
    sleep(delay)
 
some_function(3)
Producción: 

Execution took 3.003122091293335 seconds

 

  
Comprobación del parámetro de error mediante el decorador de clase: 
este tipo de decorador de clase se utiliza con mayor frecuencia. Este decorador verifica los parámetros antes de ejecutar la función, lo que evita que la función se sobrecargue y le permite almacenar solo las declaraciones lógicas y necesarias.

Python3

# Python program checking
# error parameter using
# class decorator
 
class ErrorCheck:
 
    def __init__(self, function):
        self.function = function
 
    def __call__(self, *params):
        if any([isinstance(i, str) for i in params]):
            raise TypeError("parameter cannot be a string !!")
        else:
            return self.function(*params)
 
 
@ErrorCheck
def add_numbers(*numbers):
    return sum(numbers)
 
#  returns 6
print(add_numbers(1, 2, 3))
 
# raises Error. 
print(add_numbers(1, '2', 3)) 

Producción : 
 

6
TypeError: parameter cannot be a string !!

Publicación traducida automáticamente

Artículo escrito por RishabhBhatnagar 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 *