Saltar al contenido principal

Property vs. getters y setters en Python

En este tutorial, aprenderás la diferencia entre Property de Python y los getters y setters.
· 6 min leer

Explora con IA

¿Qué son los getters y setters?

  • Getters: métodos usados en programación orientada a objetos (POO) para acceder a atributos privados de una clase.
  • Setters: métodos de POO que permiten asignar valores a atributos privados de una clase.

Atributo privado: encapsulación

Si no estás familiarizado con los atributos privados o los métodos privados en Python, lee este artículo de DataCamp.

Veamos cómo puedes implementar un atributo privado en Python.

class SampleClass:

    def __init__(self, a):
        ## private varibale or property in Python
        self.__a = a

    ## getter method to get the properties using an object
    def get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def set_a(self, a):
        self.__a = a

SampleClass tiene tres métodos.

  • __init__: se usa para inicializar los atributos o propiedades de una clase.

    • __a: es un atributo privado.
  • get_a: se usa para obtener el valor del atributo privado a.
  • set_a: se usa para asignar el valor de a utilizando un objeto de la clase.

No puedes acceder directamente a las variables privadas en Python. Por eso implementas el método getter.

Veamos cómo funciona la clase.

## creating an object
obj = SampleClass(10)

## getting the value of 'a' using get_a() method
print(obj.get_a())

## setting a new value to the 'a' using set_a() method
obj.set_a(45)

print(obj.get_a())
10
45

Así es como implementas atributos privados, getters y setters en Python. Este mismo enfoque se usaba en Java. Ahora vamos a escribir la misma implementación de una forma más pythónica.

class PythonicWay:

    def __init__(self, a):
        self.a = a

No necesitas métodos getters ni setters para acceder o cambiar los atributos. Puedes acceder directamente por el nombre del atributo.

Vamos a verlo.

## Creating an object for the 'PythonicWay' class
obj = PythonicWay(100)

print(obj.a)
100

¿Cuál es la diferencia entre las dos clases anteriores?

  • SampleClass oculta los atributos y métodos privados. Implementa la encapsulación propia de la POO.
  • PythonicWay no oculta los datos. No implementa ninguna característica de encapsulación.

¿Cuál es mejor usar?

  • Depende de lo que necesites. Si quieres atributos y métodos privados, puedes implementar la clase con métodos setters y getters; si no, puedes usar la forma normal.

Property

Ahora bien, ¿y si quieres imponer condiciones al asignar el valor de un atributo en SampleClass?

Por ejemplo: si el valor que pasamos es par y positivo, lo asignamos al atributo; en caso contrario, lo dejamos en 2.

Implementémoslo cambiando el método set_a() en SampleClass.

class SampleClass1:

    def __init__(self, a):
        ## calling the set_a() method to set the value 'a' by checking certain conditions
        self.set_a(a)

    ## getter method to get the properties using an object
    def get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def set_a(self, a):

        ## condition to check whether 'a' is suitable or not
        if a > 0 and a % 2 == 0:
            self.__a = a
        else:
            self.__a = 2

Probemos la clase creando un objeto.

## creating an object for the class 'SampleClass1'
obj = SampleClass1(16)

print(obj.get_a())
16

Veamos cómo implementar la clase anterior usando el decorador @property.

class Property:

    def __init__(self, var):
        ## initializing the attribute
        self.a = var

    @property
    def a(self):
        return self.__a

    ## the attribute name and the method name must be same which is used to set the value for the attribute
    @a.setter
    def a(self, var):
        if var > 0 and var % 2 == 0:
            self.__a = var
        else:
            self.__a = 2

@property se usa para obtener el valor de un atributo privado sin necesidad de métodos getter. Hay que anteponer @property al método que devuelve la variable privada.

Para asignar el valor de la variable privada, usamos @method_name.setter delante del método. Actúa como setter.

Probemos la clase Property para comprobar que los decoradores funcionan correctamente.

## creating an object for the class 'Property'
obj = Property(23)

print(obj.a)
2

@a.setter asignará el valor de a comprobando las condiciones que hemos definido en el método. Otra forma de usar property es...

class AnotherWay:

    def __init__(self, var):
        ## calling the set_a() method to set the value 'a' by checking certain conditions
        self.set_a(var)

    ## getter method to get the properties using an object
    def get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def set_a
    (self, var):

        ## condition to check whether var is suitable or not
        if var > 0 and var % 2 == 0:
            self.__a = var
        else:
            self.__a = 2

    a = property(get_a, set_a)

Pasa los métodos getter y setter a property y asígnalo a la variable que quieres usar como atributo de clase.

## creating an object for the 'AnotherWay' class
obj = AnotherWay(28)

print(obj.a)
28

Haz que los métodos setter y getter sean privados para ocultarlos. Vamos a ello.

class FinalClass:

    def __init__(self, var):
        ## calling the set_a() method to set the value 'a' by checking certain conditions
        self.__set_a(var)

    ## getter method to get the properties using an object
    def __get_a(self):
        return self.__a

    ## setter method to change the value 'a' using an object
    def __set_a(self, var):

        ## condition to check whether var is suitable or not
        if var > 0 and var % 2 == 0:
            self.__a = var
        else:
            self.__a = 2

    a = property(__get_a, __set_a)

Comprobemos si funciona correctamente.

## creating an object for the 'AnotherWay' class
obj = FinalClass(12)

print(obj.a)
12

Conclusión

Ya has visto cómo implementar la encapsulación en Python y la diferencia entre setter, getter y property.

Si estás empezando con Python, te recomiendo el curso gratuito de DataCamp Introduction to Python.

Si tienes alguna duda sobre el artículo, cuéntala en los comentarios. ¡Feliz programación!

Temas

Relacionado