Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Alguém poderia dar um curto exemplo de como getters exigem que se mude o código e @property não?

Isso ainda não fixou completamente na minha cabeça.

4 respostas

Digamos que você tem uma classe Pessoa e ela tem a propriedade cpf:

class Pessoa:
    def __init__(self, cpf):
        self.cpf = cpf

E que você armazena isso em um banco de dados, onde cpf é uma string, e que percebeu estão acontecendo casos do tipo na aplicação:

fulano = Pessoa('111.222.333-44')
beltrano = Pessoa('11122233344')

print(fulano.cpf)
print(beltrano.cpf)

Onde fulano e beltrano são na verdade a mesma Pessoa, então a aplicação deveria tratar isso e impedir (ou ao menos avisar sobre) o registro do segundo.

Você pode alterar a classe com:

def get_cpf(self):
    # implementação de um padrão único para representação
    return self._cpf

def set_cpf(self, valor):
    # implementação da validação, retorna erro caso inválido ou já existente
    self._cpf = valor

O que quebraria aquele print que passei antes.

Ou poderia implementar:

@property
def cpf(self):
    # implementação de um padrão único para representação
    return self._cpf

@cpf.setter
def cpf(self, valor):
    # implementação da validação, retorna erro caso inválido ou já existente
    self._cpf = valor

O que manteria a classe Pessoa funcionando como antes.

A minha pergunta vai justamente no sentido de entender na prática a razão de get_cpf quebrar o print e o @property não. A minha questão continua em aberto.

solução!

Você chegou a testar? Aqui o código completo:

class Pessoa:
    def __init__(self, cpf):
        self._cpf = cpf

    # implementação de get e set
    def get_cpf(self):
        # implementação de um padrão único para representação
        return self._cpf

    def set_cpf(self, valor):
        # implementação da validação, retorna erro caso inválido ou já existente
        self._cpf = valor

    # @property
    # def cpf(self):
    #     # implementação de um padrão único para representação
    #     return self._cpf
    #
    # @cpf.setter
    # def cpf(self, valor):
    #     # implementação da validação, retorna erro caso inválido ou já existente
    #     self._cpf = valor


fulano = Pessoa('111.222.333-44')
beltrano = Pessoa('11122233344')

print(fulano.cpf)
print(beltrano.cpf)

# a correção necessária sem usar @property
# print(fulano.get_cpf())
# print(beltrano.get_cpf())

Se o código para dar o print é:

print(fulano.cpf)
print(beltrano.cpf)

E, conforme o exemplo que dei, na necessidade de mudar a classe para aplicar a regra usando getters e setters (respectivametne get_cpf e set_cpf), o comando para dar print não vai funcionar, já que seria necessário mudar para:

print(fulano.get_cpf())
print(beltrano.get_cpf())

Não é incomum esse tipo de situação acontecer. É só pensar que a classe pessoa é importada por diversas outras aplicações e imaginar o qual trabalhoso seria achar o código e editar cada uma para alterar de print(fulano.cpf) para print(fulano.get_cpf()).

Ahhhhh, agora ficou claro como water. Obrigado pela paciência, Robson.