Python POO Intermediário
Properties
Em Python, properties permitem que você acesse métodos como se fossem atributos, mantendo a sintaxe simples de obj.x mas executando código personalizado. A decoradora @property transforma um método em um getter; para permitir atribuição, define-se um setter com @nome.setter. Isso é útil para criar atributos calculados (derivados de outros) e para validação de dados, garantindo que o objeto permaneça em estado válido.
Com properties, você pode começar com atributos públicos simples e, se precisar adicionar lógica depois, não quebra a interface existente. O acesso continua sendo obj.atributo, mas internamente o Python chama o método decorado. Além disso, properties são a maneira idiomática de implementar getters e setters em Python, evitando métodos explícitos como get_x() e set_x().
Neste card, veremos como criar uma property somente leitura (apenas getter), como adicionar validação no setter e como calcular valores dinamicamente a partir de outros atributos. Também abordaremos erros comuns, como esquecer de usar o mesmo nome no setter ou tentar modificar uma property sem setter.
Pontos-chave
- @property transforma um método em um getter acessível como atributo.
- O setter é definido com @nome.setter e permite validar ou transformar o valor antes de armazenar.
- Atributos calculados são properties que derivam seu valor de outros atributos, sem armazenar estado redundante.
- Properties mantêm a sintaxe de acesso direto, mas executam código personalizado.
- Sem setter, a property é somente leitura e tentar atribuir gera AttributeError.
class Circulo:
def __init__(self, raio):
self.raio = raio # usa o setter para validar
@property
def raio(self):
return self._raio
@raio.setter
def raio(self, valor):
if valor <= 0:
raise ValueError("O raio deve ser positivo")
self._raio = valor
@property
def area(self):
# atributo calculado: não armazena, calcula na hora
return 3.14159 * self._raio ** 2
c = Circulo(2)
print(c.raio) # 2
print(c.area) # 12.56636
c.raio = 3
print(c.area) # 28.27431
try:
c.raio = -1
except ValueError as e:
print(e) # O raio deve ser positivo