Curso
O que são getters e setters?
- Getters: métodos usados em Programação Orientada a Objetos (POO) para acessar atributos privados de uma classe.
- Setters: métodos usados em POO para definir o valor de atributos privados de uma classe.
Atributo privado - encapsulamento
Se você não está familiarizado com atributos privados ou métodos privados em Python, leia este artigo da DataCamp.
Vamos ver como implementar um atributo privado em 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 tem três métodos.
-
__init__: usado para inicializar os atributos ou propriedades de uma classe.
- __a: é um atributo privado.
- get_a: usado para obter o valor do atributo privado a.
- set_a: usado para definir o valor de a por meio de um objeto da classe.
Você não consegue acessar variáveis privadas diretamente em Python. Por isso implementamos o método getter.
Veja como a classe funciona.
## 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
É assim que você implementa atributos privados, getters e setters em Python. O mesmo processo é usado em Java. Agora, vamos escrever a mesma ideia de um jeito mais pythônico.
class PythonicWay:
def __init__(self, a):
self.a = a
Você não precisa de getters e setters para acessar ou alterar atributos. Dá para acessar diretamente pelo nome do atributo.
Veja só.
## Creating an object for the 'PythonicWay' class
obj = PythonicWay(100)
print(obj.a)
100
Qual é a diferença entre as duas classes acima?
- SampleClass esconde atributos e métodos privados. Ela implementa o recurso de encapsulamento da POO.
- PythonicWay não esconde os dados. Ela não implementa encapsulamento.
Qual é a melhor para usar?
- Depende da sua necessidade. Se você quer atributos e métodos privados, pode implementar a classe usando métodos setters e getters; caso contrário, use a forma direta.
Property
E se você quiser impor condições ao definir o valor de um atributo na SampleClass?
Por exemplo: se o valor passado for par e positivo, definimos no atributo; caso contrário, definimos 2.
Vamos implementar isso alterando o método set_a() em 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
Vamos testar a classe criando um objeto.
## creating an object for the class 'SampleClass1'
obj = SampleClass1(16)
print(obj.get_a())
16
Agora, veja como implementar a classe acima usando o 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 é usado para obter o valor de um atributo privado sem precisar de métodos getter. Basta colocar @property acima do método que retorna a variável privada.
Para definir o valor da variável privada, usamos @method_name.setter acima do método que atuará como setter.
Vamos testar a classe Property para ver se os decorators estão funcionando corretamente.
## creating an object for the class 'Property'
obj = Property(23)
print(obj.a)
2
O @a.setter define o valor de a verificando as condições que especificamos no método. Outra forma de usar property é...
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)
Passe os métodos getter e setter para property e atribua ao nome que você quer usar como atributo da classe.
## creating an object for the 'AnotherWay' class
obj = AnotherWay(28)
print(obj.a)
28
Deixe os métodos setter e getter privados para escondê-los. Vamos fazer isso.
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)
Vamos conferir se está funcionando direitinho.
## creating an object for the 'AnotherWay' class
obj = FinalClass(12)
print(obj.a)
12
Conclusão
Agora você viu como implementar encapsulamento em Python e a diferença entre setter, getter e property.
Se você está começando em Python, recomendo o curso gratuito da DataCamp Introduction to Python.
Ficou com alguma dúvida sobre o artigo? Deixe seu comentário. Bons códigos!