Curso
¿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!