1
resposta

'Conta' object has no attribute 'saldo' - Curiosidade

Opa pessoal, como estão? tudo certo? Estava eu aqui nos meus estudos e me deparei com um problema aqui. Ele ja foi mencionado em outros tópicos aqui, mas eu queria me aprofundar, pela curiosidade :D

Após definir um getter e um setter para a propriedade Limite, nao consigo acessar o atributo 'conta.saldo'. Tem algum motivo para isso? Eu somente consegui acessar a propriedade saldo após colocar um @property para a funçao def saldo(self) ... ps: primeiro post aqui, nao sei se a formatação ficou legal, qlq coisa estou atento para quando responderem xD

class Conta:
    def __init__(self, numero, titular, saldo, limite):

        print("construindo objeto ...{}".format(self))
        self.__numero = numero
        self.__titular = titular
        self.__saldo = saldo
        self.__limite = limite

    def extrato(self):
        print("Saldo de {} do titular {}".format(self.__saldo, self.__titular))

    def deposita(self, valor):
        self.__saldo += valor

    def saca(self, valor):
        if(valor <= (self.__saldo + self.__limite)):
            self.__saldo -= valor
        else:
            print("O valor {} passou o limite.".format(valor))
    def transfere(self, valor, origem, destino):
        self.saca(valor)
        destino.deposita(valor)


    def get_saldo(self):
        return self.__saldo

    def get_titular(self):
        return self.__titular

    @property 
    def limite(self):
        return self.__limite

    @limite.setter
    def limite(self, limite):
        self.__limite = limite

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

1 resposta

Assiste esse video (em ingles) sobre isso que é excelente, ja deve estar no tempo certo, se n estiver coloca no 37:51 que é onde começa a parte que você ta em duvida.

Te explicando de maneira simples, no python a gente faz getters e setters sem colocar get_ ou set_ na frente da variavel, o motivo disso é conseguir manter o seu código funcionando sem precisar fazer nenhuma modificação em sistemas que já utilizavam a classe antes de ela ter um getter e/ou um setter.

Então ao invés de privarmos nosso self.saldo e criarmos um getter e um setter com get_saldo e set_saldo fazendo com que todo mundo que usava o self.saldo precise mudar pra voltar a ter seu código funcionando, você priva sua variavel e cria seu getter e setter usando o @property e o @sua_variavel.setter.

Na forma não pythonica você faz assim:

class Exemplo:
        def __init__(self, saldo):
                self.__saldo = saldo
        def get_saldo(self): # em algum momento você refatora e coloca o getter e o setter
                pass
        def set_saldo(self):
                pass
exemplo = Exemplo(100)
exemplo.saldo # printa o erro que você teve
>>> AttributeError: 'Exemplo' object has no attribute 'saldo'

Agora se você fazer da maneira pythonica:

class Exemplo:
        def __init__(self, saldo):
                self.__saldo = saldo
        @property # getter pythonico
        def saldo(self): # em algum momento você refatora e coloca o getter e o setter
                pass
        @saldo.setter # setter pythonico
        def saldo(self):
                pass
exemplo = Exemplo(100)
exemplo.saldo # continua funcionando sem problema e você não precisou mudar seu código