Neste post mostro um exemplo de como criar getters e setters de forma que você possa criar fluxos mais complexos. O exemplo que utilizo vai ser uma classe que te informa se ela foi modificada ou nao desde que foi criada.
A classe que vou utilizar chama-se User e possui as seguintes propriedades: Name, Login, Password, Email e uma “propriedade privada” chamada “is_modified”.
Veja o código:
class User(object): def __init__(self, name: str, login: str, password: str, email: str): self.name = name self.login = login self.password = password self.email = email self.__is_modified__ = False def is_modified(self): return self.__is_modified__
Bom, esta é uma classe normal. Nada demais nela. O que vamos fazer agora é adicionar 2 métodos para cada uma das propriedades (exceto a __is_modified__, ela nao deve ser acessada de fora da classe).
Começando pela propriedade name, vamos fazer o getter:
@property def name(self): return self.__name
O getter é composto pelo decorator @property (nativo do python, nao precisa instalar pacotes extras), o método com o mesmo nome da propriedade que queremos criar o getter e o setter. (no caso, name). Este método apenas retorna uma propriedade chamada __name. Todavia, este nome é arbitrário, você pode colocar o nome que desejar, mas repetir o nome da propriedade, incluindo os indicadores de que ela é privada, costuma a ser uma boa ideia.
Agora vamos fazer o setter da propriedade name:
@name.setter def name(self, value): if value is None: raise ValueError("Name cannot be none!") self.__is_modified__ = True self.__name = value
O decorator do setter é o nome do método getter, chamando o setter (@name.setter). Este método recebe um argumento, que é o novo valor da propriedade.
Você nao precisa, mas eu coloquei uma validação ali. O nome não pode ser nulo. Então, se a pessoa tentar passar uma string nula como o nome, será lançada uma exception. Também mudei o valor da propriedade __is_modified__ para True e depois fiz o que o setter deveria fazer: definir o valor da propriedade Name.
Assim como no setter, a propriedade interna nao precisa se chamar __name, mas elas tem que ter o mesmo nome entre si, ou seja, o que você usar no setter, tem que usar no getter.
A apliquei a mesma lógica as outras propriedades da classe:
class User(object): def __init__(self, name: str, login: str, password: str, email: str): self.name = name self.login = login self.password = password self.email = email self.__is_modified__ = False def is_modified(self): return self.__is_modified__ @property def name(self): return self.__name @name.setter def name(self, value): if value is None: raise ValueError("Name cannot be none!") self.__is_modified__ = True self.__name = value @property def login(self): return self.__login @login.setter def login(self, value): if value is None: raise ValueError("Login cannot be none!") self.__is_modified__ = True self.__login = value @property def password(self): return self.__password @password.setter def password(self, value): if value is None: raise ValueError("Password cannot be none!") self.__is_modified__ = True self.__password = value @property def email(self): return self.__email @email.setter def email(self, value): if value is None: raise ValueError("Email cannot be none!") self.__is_modified__ = True self.__email = value
Obviamente, a classe ficou bem maior, mas agora temos o controle sobre o que é devolvido e definido em cada propriedade da classe. No caso, garanti que nenhuma das propriedades dela serão nulas.
Agora para testar o método que detecta se o objeto foi modificado:
if __name__ == '__main__': user = User(name="John User", login="j.user", email="j.user@gmail.com", password="p4ssw0rd!") print(f"Created an User. Is it modified? {user.is_modified()}") user.name = "Updated name" print(f"Changed an User. Is it modified? {user.is_modified()}")
Exemplo de saída:
Created an User. Is it modified? False Changed an User. Is it modified? True
Coloquei este exemplo no meu Github.
Espero ter ajudado!
Latest posts by Breno RdV (see all)
- Estamos de mudança! - abril 28, 2024
- O que é Metaclass e como ela funciona. (#python #dev #metaclass) - janeiro 11, 2023
- Entenda a mágica dos Generators. (#python, #dev, #generator, #iterator) - dezembro 28, 2022