Imagen por editor
Python, con su sintaxis limpia y legible, es un lenguaje de programación de alto nivel ampliamente utilizado. Python está diseñado para ser fácil de usar y enfatiza la simplicidad y el costo reducido de mantenimiento del programa. Viene con una biblioteca extensa que reduce la necesidad de que los desarrolladores escriban código desde cero y aumenta la productividad de los desarrolladores. Una característica poderosa de Python que contribuye a la elegancia del código son los decoradores.
En Python, un decorador es una función que le permite modificar el comportamiento de otra función sin cambiar su lógica central. Toma otra función como argumento y devuelve la función con funcionalidad extendida. De esta manera, puedes usar decoradores para agregar algo de lógica adicional a las funciones existentes para aumentar la reutilización con solo unas pocas líneas de código. En este artículo, exploraremos ocho decoradores de Python integrados que pueden ayudarlo a escribir código más elegante y fácil de mantener.
Imagen por editor
El @atexit.register
El decorador se utiliza para registrar una función que se ejecutará al finalizar el programa. Esta función se puede utilizar para realizar cualquier tarea cuando el programa está a punto de salir, ya sea por una ejecución normal o por un error inesperado.
Ejemplo:
import atexit
# Register the exit_handler function
@atexit.register
def exit_handler():
print("Exiting the program. Cleanup tasks can be performed here.")
# Rest of the program
def main():
print("Inside the main function.")
# Your program logic goes here.
if __name__ == "__main__":
main()
Salida:
Inside the main function.
Exiting the program. Cleanup tasks can be performed here.
En la implementación anterior, @atexit.register
se menciona arriba de la definición de la función. Define el exit_handler()
funcionar como una función de salida. Básicamente, significa que cada vez que el programa llega a su punto de terminación, ya sea mediante ejecución normal o debido a un error inesperado que causa una salida prematura, el exit_handler()
Se invocará la función.
El @dataclasses.dataclass
es un poderoso decorador que se utiliza para generar automáticamente métodos especiales comunes para clases como “__init__”, “__repr__” y otras. Le ayuda a escribir código más limpio y conciso al eliminar la necesidad de escribir métodos repetitivos para inicializar y comparar instancias de su clase. También puede ayudar a prevenir errores al garantizar que los métodos especiales comunes se implementen de manera consistente en todo su código base.
Ejemplo:
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
point = Point(x=3, y=2)
# Printing object
print(point)
# Checking for the equality of two objects
point1 = Point(x=1, y=2)
point2 = Point(x=1, y=2)
print(point1 == point2)
Salida:
Point(x=3, y=2)
True
El @dataclass
El decorador, aplicado encima de la definición de la clase Point, indica a Python que utilice el comportamiento predeterminado para generar métodos especiales. Esto crea automáticamente el __init__
método, que inicializa los atributos de clase, como x e y, al crear una instancia del objeto. Como resultado, se pueden construir instancias como point sin necesidad de codificación explícita. Además, el __repr__
El método, responsable de proporcionar una representación de cadena de objetos, también se ajusta automáticamente. Esto garantiza que cuando se imprime un objeto, como un punto, se obtiene una representación clara y ordenada, como se ve en el resultado: Punto(x=3, y=2). Además, la comparación de igualdad (==) entre dos instancias, punto1 y punto2, produce Verdadero. Esto es digno de mención porque, de forma predeterminada, Python verifica la igualdad según la ubicación de la memoria. Sin embargo, en el contexto de los objetos de clase de datos, la igualdad está determinada por los datos contenidos en ellos. Esto se debe a que el decorador @dataclass genera un __eq__
Método que verifica la igualdad de los datos presentes en los objetos, en lugar de verificar la misma ubicación de memoria.
El @enum.unique
El decorador, que se encuentra en el módulo enum, se utiliza para garantizar que los valores de todos los miembros de una enumeración sean únicos. Esto ayuda a evitar la creación accidental de varios miembros de enumeración con el mismo valor, lo que puede generar confusión y errores. Si se encuentran valores duplicados, se ValorError es elevado.
Ejemplo:
from enum import Enum, unique
@unique
class VehicleType(Enum):
CAR = 1
TRUCK = 2
MOTORCYCLE = 3
BUS = 4
# Attempting to create an enumeration with a duplicate value will raise a ValueError
try:
@unique
class DuplicateVehicleType(Enum):
CAR = 1
TRUCK = 2
MOTORCYCLE = 3
# BUS and MOTORCYCLE have duplicate values
BUS = 3
except ValueError as e:
print(f"Error: {e}")
Salida:
Error: duplicate values found in : BUS -> MOTORCYCLE
En la implementación anterior, “BUS” y “MOTORCYCLE” tienen el mismo valor “3”. Como resultado, el @unique
El decorador genera un ValueError con un mensaje que indica que se han encontrado valores duplicados. Tampoco puedes utilizar la misma clave más de una vez ni asignar el mismo valor a diferentes miembros. De esta manera, ayuda a evitar valores duplicados para varios miembros de la enumeración.
El partial
decorador es una herramienta poderosa que se utiliza para crear funciones parciales. Las funciones parciales le permiten preestablecer algunos de los argumentos de la función original y generar una nueva función con esos argumentos ya completados.
Ejemplo:
from functools import partial
# Original function
def power(base, exponent):
return base ** exponent
# Creating a partial function with the exponent fixed to 2
square = partial(power, exponent=2)
# Using the partial function
result = square(3)
print("Output:",result)
Salida:
En la implementación anterior, tenemos una función "potencia" que acepta dos argumentos "base" y "exponente" y devuelve el resultado de la base elevada a la potencia del exponente. Hemos creado una función parcial llamada "cuadrado" usando la función original en la que el exponente está preestablecido en 2. De esta manera, podemos ampliar la funcionalidad de las funciones originales usando una partial
decorador.
El @singledisptach
El decorador se utiliza para crear funciones genéricas. Le permite definir diferentes implementaciones de funciones con el mismo nombre pero diferentes tipos de argumentos. Es particularmente útil cuando desea que su código se comporte de manera diferente para diferentes tipos de datos.
Ejemplo:
from functools import singledispatch
# Decorator
@singledispatch
def display_info(arg):
print(f"Generic: {arg}")
# Registering specialized implementations for different types
@display_info.register(int)
def display_int(arg):
print(f"Received an integer: {arg}")
@display_info.register(float)
def display_float(arg):
print(f"Received a float: {arg}")
@display_info.register(str)
def display_str(arg):
print(f"Received a string: {arg}")
@display_info.register(list)
def display_sequence(arg):
print(f"Received a sequence: {arg}")
# Using the generic function with different types
display_info(39)
display_info(3.19)
display_info("Hello World!")
display_info([2, 4, 6])
Salida:
Received an integer: 39
Received a float: 3.19
Received a string: Hello World!
Received a sequence: [2, 4, 6]
En la implementación anterior, primero desarrollamos la función genérica display_info()
usando el @singledisptach
decorador y luego registró su implementación para int, float, string y list por separado. El resultado muestra el funcionamiento de display_info()
para tipos de datos separados.
El @classmethod
es un decorador utilizado para definir métodos de clase dentro de la clase. Los métodos de clase están vinculados a la clase y no al objeto de la clase. La principal distinción entre métodos estáticos y métodos de clase radica en su interacción con el estado de la clase. Los métodos de clase tienen acceso y pueden modificar el estado de la clase, mientras que los métodos estáticos no pueden acceder al estado de la clase y operar de forma independiente.
Ejemplo:
class Student:
total_students = 0
def __init__(self, name, age):
self.name = name
self.age = age
Student.total_students += 1
@classmethod
def increment_total_students(cls):
cls.total_students += 1
print(f"Class method called. Total students now: {cls.total_students}")
# Creating instances of the class
student1 = Student(name="Tom", age=20)
student2 = Student(name="Cruise", age=22)
# Calling the class method
Student.increment_total_students() #Total students now: 3
# Accessing the class variable
print(f"Total students from student 1: {student1.total_students}")
print(f"Total students from student 2: {student2.total_students}")
Salida:
Class method called. Total students now: 3
Total students from student 1: 3
Total students from student 2: 3
En la implementación anterior, el Estudiante la clase tiene total_estudiantes como variable de clase. El @classmethod
El decorador se utiliza para definir el increment_total_students()
método de clase para incrementar el total_estudiantes variable. Siempre que creamos una instancia de la clase Estudiante, el número total de estudiantes se incrementa en uno. Creamos dos instancias de la clase y luego usamos el método de clase para modificar la total_estudiantes variable a 3, que también se refleja en las instancias de la clase.
El @staticmethod
El decorador se utiliza para definir métodos estáticos dentro de una clase. Los métodos estáticos son los métodos que se pueden llamar sin crear una instancia de la clase. Los métodos estáticos se utilizan a menudo cuando no tienen que acceder a parámetros relacionados con objetos y están más relacionados con la clase en su conjunto.
Ejemplo:
class MathOperations:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def subtract(x, y):
return x - y
# Using the static methods without creating an instance of the class
sum_result = MathOperations.add(5, 4)
difference_result = MathOperations.subtract(8, 3)
print("Sum:", sum_result)
print("Difference:", difference_result)
Salida:
Sum: 9
Difference: 5
En la implementación anterior, hemos utilizado @staticmethod
para definir un método estático add() para la clase “MathOperations”. Hemos agregado los dos números "4" y "5" lo que da como resultado "9" sin crear ninguna instancia de la clase. De manera similar, resta los dos números "8" y "3" para obtener "5". De esta manera se pueden generar métodos estáticos para realizar funciones de utilidad que no requieren el estado de una instancia.
El @property
El decorador se utiliza para definir los métodos getter para el atributo de clase. Los métodos getter son los métodos que devuelven el valor de un atributo. Estos métodos se utilizan para la encapsulación de datos que especifica quién puede acceder a los detalles de la clase o instancia.
Ejemplo:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
# Getter method for the radius.
return self._radius
@property
def area(self):
# Getter method for the area.
return 3.14 * self._radius**2
# Creating an instance of the Circle class
my_circle = Circle(radius=5)
# Accessing properties using the @property decorator
print("Radius:", my_circle.radius)
print("Area:", my_circle.area)
Salida:
Radius: 5
Area: 78.5
En la implementación anterior, la clase "Círculo" tiene un atributo "radio". Hemos usado @property
para configurar los métodos getter para el radio y el área. Proporciona una interfaz limpia y coherente para que los usuarios de la clase accedan a estos atributos.
Este artículo destaca algunos de los decoradores más versátiles y funcionales que puede utilizar para hacer que su código sea más flexible y legible. Estos decoradores le permiten ampliar las funcionalidades de la función original para hacerla más organizada y menos propensa a errores. Son como toques mágicos que hacen que sus programas Python se vean limpios y funcionen sin problemas.
Kanwal Mehreen es un aspirante a desarrollador de software con un gran interés en la ciencia de datos y las aplicaciones de IA en medicina. Kanwal fue seleccionado como Google Generation Scholar 2022 para la región APAC. A Kanwal le encanta compartir conocimientos técnicos escribiendo artículos sobre temas de actualidad y le apasiona mejorar la representación de las mujeres en la industria tecnológica.
- Distribución de relaciones públicas y contenido potenciado por SEO. Consiga amplificado hoy.
- PlatoData.Network Vertical Generativo Ai. Empodérate. Accede Aquí.
- PlatoAiStream. Inteligencia Web3. Conocimiento amplificado. Accede Aquí.
- PlatoESG. Carbón, tecnología limpia, Energía, Ambiente, Solar, Gestión de residuos. Accede Aquí.
- PlatoSalud. Inteligencia en Biotecnología y Ensayos Clínicos. Accede Aquí.
- Fuente: https://www.kdnuggets.com/8-built-in-python-decorators-to-write-elegant-code?utm_source=rss&utm_medium=rss&utm_campaign=8-built-in-python-decorators-to-write-elegant-code