Los decoradores son una herramienta en Python que permiten modificar la funcionalidad de una función, método o clase sin tener que modificar directamente su código. En Python, una función es un objeto, por lo que se puede "decorar" agregando más funcionalidad a esa función en tiempo de ejecución mediante la adición de una función de decoración. Los decoradores se aplican utilizando el símbolo "@", seguido del nombre del decorador.
Ejemplo de decorador en Python
import time
# Define el decorador timer
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs) # Llama a la función decorada con los argumentos proporcionados
end_time = time.time()
print("Tiempo de ejecución:", end_time - start_time, "segundos")
return result
return wrapper
# Aplica el decorador a la función
@timer
def my_function():
time.sleep(2)
# Llama a la función decorada
my_function()
En este ejemplo, el decorador "timer" se define como una función que toma como argumento otra función. Dentro de "timer", se define otra función llamada "wrapper" que mide el tiempo de ejecución de la función original "my_function" y lo imprime. Luego, "wrapper" llama a la función original "my_function" y devuelve su resultado.
La metaprogramación se refiere a la capacidad del lenguaje de programación para crear, modificar o analizar código en tiempo de ejecución. En Python, esto se logra a través de la introspección y la capacidad de Python de tratar a las funciones y las clases como objetos.
Ejemplo de metaprogramación en Python
# Diccionario que define la nueva clase
class_dict = {
"name": "MyClass", # Nombre de la clase
"attributes": { # Atributos de la clase
"foo": 123, # Atributo foo con valor 123
"bar": "abc", # Atributo bar con valor "abc"
},
}
# Función para crear la clase dinámicamente
def create_class(class_dict):
# Utiliza la función type() para crear una nueva clase
new_class = type(class_dict["name"], (), class_dict["attributes"])
return new_class
# Crea la nueva clase utilizando el diccionario
MyClass = create_class(class_dict)
# Accede a los atributos de la clase
print(MyClass.foo) # Imprime: 123
print(MyClass.bar) # Imprime: "abc"
En este ejemplo, la función "create_class" toma un diccionario que describe una clase, utiliza el constructor de "type" para crear una nueva clase a partir del nombre y atributos proporcionados, y devuelve la clase recién creada. Luego, la variable "MyClass" se establece en el resultado de llamar a "create_class", lo que permite acceder a los atributos de "foo" y "bar" de la nueva clase.