Quais são as diferença entre os metodos com @property e os sem?
Quais são as diferença entre os metodos com @property e os sem?
Olá, Caio.
O uso do decorator @property
são a maneira "pythonica" de se trabalhar com atributos, pois:
getters
e setters
) para validar novos valores e evitar acessar ou modificar os dados diretamente.@property
, você pode "reutilizar" o nome de uma propriedade para evitar a criação de novos nomes para os getters
, setters
e deleters
.O utilizador da classe não vai perceber se o criador usa ou não @property
em seus atributos.
Imagine que você queira criar a seguinte classe:
class House:
def __init__(self, price):
self.price = price
O atributo price
pode facilmente ser acessado ou modificado usando:
# Acessar
obj.price
# Modificar
obj.price = 40000
Agora imagine que você usa essa classe em produção, mas agora deseje adicionar getters
e setters
ao atributo price
. Você teria que mudar todas as linhas de acesso e modificação para:
# Acessar
obj.get_price()
# Modificar
obj.set_price(40000)
Caso contrário, o código pararia.
Se você decidir usar @property
, sua classe será semelhante ao exemplo abaixo:
class House:
def __init__(self, price):
self._price = price
@property
def price(self):
return self._price
@price.setter
def price(self, new_price):
if new_price > 0 and isinstance(new_price, float):
self._price = new_price
else:
print("Please enter a valid price")
Observe que o atributo price agora é considerado "protegido" porque adicionamos um sublinhado à esquerda ao nome em self._price
. No Python, por escolha, quando você adiciona um sublinhado inicial a um nome, está dizendo a outros desenvolvedores que ele não deve ser acessado ou modificado diretamente fora da classe. Só deve ser acessado através de intermediários (getters e setters) se estiverem disponíveis.
Com a utilização de @property
, o acesso e modificação permanacem os mesmos:
# Acessar
obj.price
# Modificar
obj.price = 40000
Além disso, como adicionamos uma nova regra de negócio ao atributo. Se tentarmos atribuir um valor inválido, vemos a mensagem descritiva. O código a seguir:
house = House(50000.0)
house.price = -50
Apresentaria o seguinte erro: Please enter a valid price
. Além disso, seu valor não seria atualizado.
Você não precisa necessariamente definir os três métodos para cada atributo. Você pode definir propriedades somente leitura incluindo apenas um método getter
. Você também pode optar por definir um getter
e um setter
sem um deleter
.
Se você acha que um atributo deve ser definido apenas quando a instância é criada ou que somente deve ser modificado internamente na classe, você pode omitir o configurador.
Você pode escolher quais métodos incluir, dependendo do contexto em que estiver trabalhando.
Em suma:
@property
, que é mais compacta e legível.@property
pode ser considerada a maneira "pytônica" de definir getters
, setters
e deleters
.getters
, setters
e deleters
que atuam como intermediários "nos bastidores" para evitar acessar ou modificar os dados diretamente.Espero ter ajudado.