Entendiendo atributos y métodos en Python

En este artículo exploraremos un error común en programación Python que nos ayudará a comprender mejor los conceptos de clases, objetos, atributos y métodos.

Es importante recordar que Python es un lenguaje dinámico, lo que significa que podemos agregar o modificar atributos y métodos en cualquier momento. Además, Python no soporta la sobrecarag de métodos; si definimos varias veces el mismo método, la última definición sobreescribirá las anteriores. Cuando utilizamos decoradores, podemos transformar métodos en propiedades, permitiando crear métodos con el mismo nombre pero diferentes decoradores.

class Empleado():
    
    def __init__(self, nombre, salario):
        self._nombre = nombre
        self._salario = salario
        
    # @property
    def nombre(self):
        return self._nombre
    
    # @property
    def salario(self):
        return self._salario
    
    # @salario.setter
    def salario(self, valor):
        # Sin el decorador @property, este método sobreescribiría salario(self)
        self._salario = valor
    
trabajador = Empleado('maria', 50000)
# print(trabajador.salario()) # ERROR, porque el método salario(self) fue sobrescrito
trabajador.salario(60000) # Llama al método salario(self, valor), estableciendo el nuevo salario
print(trabajador.salario) # Muestra la dirección del método salario() del objeto
trabajador.nuevosalario = 60000 # El objeto originalmente no tenía el atributo nuevo_salario
trabajador.salario = 60000 # Esto modifica el atributo salario del objeto
# trabajador.salario(70000) # ERROR, 'int' object is not callable. El atributo salario ya no es un método

Claramente, esta capacidad de agregar atributos dinámicamente puede presentar riesgos. Si necesitamos restringir los atributos que un objeto puede tener, podemos definir la varible __slots__ en nuestra clase. Es importante notar que esta restricción solo afecta a los objetos de la clase actual y no a sus subclases.

Ejemplo:

class Empleado():
    
    __slots__ = ('_nombre', '_salario')

    def __init__(self, nombre, salario):
        self._nombre = nombre
        self._salario = salario

    def agregar_atributo(self, attr):
        self._attr = attr
    
    @property
    def nombre(self):
        return self._nombre
    
    @property
    def salario(self):
        return self._salario
    
    @salario.setter
    def salario(self, valor):
        self._salario = valor
    

def principal():
    trabajador = Empleado('maria', 50000)
    trabajador.salario = 60000
    # trabajador._nombre = 'luis' # Es posible acceder directamente al atributo
	trabajador.agregar_atributo(123) # ERROR, 'Empleado' object has no attribute '_attr'


Etiquetas: Python POO atributos métodos __slots__

Publicado el 6-22 07:35