Desarrollo con Python
  • Conceptos básicos
    • 🐍Introducción a Python
      • 🐍Variables
      • 🐍Strings
      • 🐍Números
      • 🐍Comentarios
      • 🐍Funciones
      • 🐍Funciones Propias
      • 🐍Zen of Python
    • 💿Primer programa
  • Operadores en python
    • ❎Operadores
      • ❎Operadores Aritméticos
      • ❎Operadores de asignación
      • ❎Booleanos
      • ❎Operadores de comparación
      • ❎Operadores lógicos
      • ❎Operadores de identidad
      • ❎Operadores de pertenencia
  • Datos Complejos
    • ▶️Datos complejos
      • ▶️Listas
      • ▶️Tuplas
      • ▶️Diccionarios
      • ▶️Bytes y Bytearrays
      • ▶️Sets
      • ▶️NoneType
    • 💿Caso práctico: Agenda
  • Control de flujo
    • 🛑Estructuras de control de flujo
      • 🛑Sentencias if/elif/else
      • 🛑Sentencia for
      • 🛑Sentencia while
      • 🛑break/continue/pass
    • ⚠️Excepciones en Python3
    • 🎯Caso práctico: 4 in Row
  • Orientacion a objetos
    • 💾Scope y Namespaces
    • 💾Clases en Python 3
    • 💾Métodos y atributos
    • 💾Clases y Objetos
    • 💾Decorators
  • Trabajando con objetos
    • 🔢Trabajando con Objetos
      • 🔢Trabajando con Números
      • 🔢Trabajando con Strings
      • 🔢Trabajando con Listas
      • 🔢Trabajando con Tuplas
      • 🔢Trabajando con Sets
      • 🔢Trabajando con Diccionarios
  • Programación Modular
    • 🧩Programación modular
      • 🧩Paquetes
      • 🧩PIP y paquetes externos
      • 🧩Pandas
      • 🧩NumPy
      • 🧩Matplotlib
      • 📄Caso Práctico
  • Proyectos finales
    • 🐍Videojuego Snake
    • 📥Detección de Spam con Machine Learning
Con tecnología de GitBook
En esta página
  • 1. Conceptos avanzados sobre funciones
  • 2. ¿Qué es un decorator?
  • 3. Syntactic Sugar
  • 4. Decorators en las Clases
  1. Orientacion a objetos

Decorators

1. Conceptos avanzados sobre funciones

En Python las funciones también se consideran objetos y como consecuencia de esto se pueden asignar a una variable, almacenarlas en estructuras de datos (listas, tuplas, diccionarios...) o incluso pasarlas como argumento de otras funciones.

def func():
    print("Hola mundo")
    
func()
Hola mundo

func
<function __main__.func()>

var = func

var()
Hola mundo

def func2(funcion):
    funcion()
    
func2(func)
Hola mundo

2. ¿Qué es un decorator?

Los decorator envuelven una función, modificando su comportamiento realizando una combinación de todas las propiedades que hemos visto anteriormente.

def mi_funcion():
    print("Hola mundo")
    
# Añadimos nuevas funcionalidades a una función ya existente
def mi_decorator(func):
    def wrapper():
        print("Ejecución antes de la llamada a la funcion")
        func()
        print("Ejecución después de la llamada a la funcion")
    return wrapper
    
mi_funcion_mod = mi_decorator(mi_funcion)

mi_funcion_mod()
Ejecución antes de la llamada a la funcion
Hola mundo
Ejecución después de la llamada a la funcion

Podemos utilizar decorators para modificar el comportamiento de una función que programemos, por ejemplo, añadiendo condiciones que se evalúen antes de ejecutar la función ya existente que no queremos modificar.

def funcion():
    print("Hola mundo")
    
def mi_decorator(func):
    def wrapper():
        if var < 5:
            func()
        else:
            print("No se puede ejecutar la funcion")
    return wrapper
    
funcion = mi_decorator(funcion)

var = 2

funcion()
Hola mundo

var = 10

funcion()
No se puede ejecutar la funcion

3. Syntactic Sugar

La sintaxis que hemos utilizado en el apartado anterior para definir el decorator es bastante compleja, por ello, Python nos proporciona una alternativa mucho más sencilla.

def mi_decorator(func):
    def wrapper():
        print("Ejecución antes de la llamada a la funcion")
        func()
        print("Ejecución después de la llamada a la funcion")
    return wrapper

# Añadimos @ y el decorador a aplicar a una función  
@mi_decorator
def funcion():
    print("Hola mundo")
    
funcion()
Ejecución antes de la llamada a la funcion
Hola mundo
Ejecución después de la llamada a la funcion

4. Decorators en las Clases

Una de las cosas interesantes sobre los decorators es que Python nos proporciona varios definidos por defecto que podemos utilizar dentro de una clase.

Uno de los decorators más interesantes que podemos utilizar es @property, que nos permite definir métodos en una clase para consultar y modificar un atributo interno.

# Clase modificada

class Coche():
    """Esta clase representa un coche."""
    def __init__(self, modelo, potencia, consumo):
        """Inicializa los atributos de instancia.
        Argumentos posicionales:
        modelo -- string que representa el modelo del coche
        potencia -- int que representa la potencia en cv
        conumo -- int que representa el consumo en l/100km
        """
        self._modelo = modelo
        self._potencia = potencia
        self._consumo = consumo
        self._km_actuales = 0
    def especificaciones(self):
        """Muestra las especicificaciones del coche."""
        print("Modelo:", self._modelo,
             "\nPotencia: {} cv".format(self._potencia),
             "\nConsumo: {} l/100km".format(self._consumo),
             "\nKilometros actuales:", self._km_actuales)
             
    @property
    def kilometros(self):
        return self._km_actuales
        
    @kilometros.setter
    def kilometros(self, kilometros):
        """Actualiza los kilometros del coche."""
        if kilometros > self._km_actuales:
            self._km_actuales = kilometros
        else:
            print("ERROR: No se puede establecer un numero de kilometros inferior al actual")
            
    def consumo_total(self):
        """Muestra el consumo total del coche desde el kilometro 0."""
        consumo_total = (self._km_actuales / 100) * self._consumo
        print("El consumo total es de {} litros".format(consumo_total))
bmw = Coche("bmw i3", 150, 6)

# Esto es una mala práctica
bmw._km_actuales
0

# Buena práctica
bmw.kilometros
0

bmw.kilometros = 500

bmw.especificaciones()
Modelo: bmw i3 
Potencia: 150 cv 
Consumo: 6 l/100km 
Kilometros actuales: 500

bmw.kilometros
500

bmw.kilometros = 200
ERROR: No se puede establecer un numero de kilometros inferior al actual

AnteriorClases y ObjetosSiguienteTrabajando con Objetos

Última actualización hace 1 año

💾
Page cover image