Oi, Renato.
O que é o @property?
Imagine que você tem um dado que não existe fisicamente como uma variável fixa, mas que pode ser calculado a partir de outras informações. Ou imagine que você quer proteger um atributo para que ninguém mude o valor dele sem passar por uma validação.
O @property transforma um método em um atributo virtual.
Por que usar?
- Sintaxe limpa: Você acessa como
pessoa.saudacao em vez de chamar uma função pessoa.saudacao(). - Lógica oculta: O usuário da sua classe acha que está apenas lendo uma variável, mas por trás você pode estar formatando strings, fazendo cálculos ou buscando dados em outro lugar.
- Proteção: Você pode criar propriedades que só permitem a leitura, impedindo que alguém altere um valor importante acidentalmente.
Exemplo prático:
Pense em um retângulo. Você tem a largura e a altura. A area não precisa ser guardada em uma variável (pois se a largura mudar, a área guardada ficaria errada). Você cria uma @property area que calcula o valor na hora em que for pedida.
O que é o @classmethod?
Enquanto os métodos comuns trabalham com os dados de uma pessoa específica (o self), o @classmethod trabalha com a classe como um todo (o cls).
Por que usar?
- Fábricas de objetos: Usado para criar novas instâncias de formas diferentes. Por exemplo, criar uma
Pessoa a partir de um ano de nascimento em vez da idade direta. - Configurações globais: Alterar algo que afete todos os objetos daquela classe simultaneamente.
Comparação Direta
| Característica | @property | @classmethod |
|---|
| Foco | O objeto individual (instância). | A estrutura da classe. |
| Acesso | objeto.nome_propriedade (sem parênteses). | Classe.metodo() ou objeto.metodo(). |
| Referência | Usa self para acessar dados do objeto. | Usa cls para acessar a própria classe. |
| Intuito | Representar um dado/estado. | Executar uma ação lógica da classe. |
Exemplo aplicado:
Vamos ajustar sua classe para mostrar os dois em ação:
class Pessoa:
def __init__(self, nome='', idade=0, profissao=''):
self.nome = nome.title()
self.idade = idade
self.profissao = profissao
# PROPERTY: se comporta como um atributo (valor)
@property
def saudacao(self):
return f'Saudações, {self.nome}! Profissão: {self.profissao}'
# CLASSMETHOD: uma "fábrica" para criar pessoas de outro jeito
@classmethod
def criar_crianca(cls, nome):
# retorna uma nova instância da classe com idade 0 e sem profissão
return cls(nome, 0, 'Estudante')
# uso da Property (acesso direto)
alguem = Pessoa('Renato', 30, 'Dev')
print(alguem.saudacao)
# uso do Classmethod (chamado pela Classe)
crianca = Pessoa.criar_crianca('Zezinho')
print(crianca)
No seu código original, a saudacao faz total sentido como @property porque ela descreve um estado daquela pessoa específica. Já o @classmethod seria útil se você precisasse de uma função para contar quantas pessoas foram criadas no total ou para criar perfis padrão de usuários.
Espero ter ajudado.
Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!