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

Dúvida a respeito de atributos privados

Boa noite gente, estou estudando POO em Python e durante o curso me deparei com a seguinte situação:

Nas aulas, o instrutor nos ensina sobre atributos privados, e explica que com dois underscores, você avisa que aquele atributo é privado, e portanto não deve ser alterado (mesmo que ainda possa ser).

Até então ok, porém pouco mais adiante em um exercício vemos o seguinte código:

class Retangulo:

    def __init__(self, x, y):
        self.__x = x
        self.__y = y
        self.__area = x * y

    def obter_area(self):
        return self.__area

r = Retangulo(7,6)
r.area = 7
print(r.obter_area())

Onde a pergunta é: Com base no código a seguir, o que acontecerá ao executar r.obter_area() após tentar modificar o valor de r.area?

E a resposta: Imprime o valor de 42, pois o encapsulamento impede a alteração direta da variável 'area'. A variável 'area' está encapsulada pelo uso do prefixo '__', o que impede a alteração direta de seu valor. Portanto, o método 'obter_area()' retorna o valor calculado no momento da instanciação do objeto 'r' (7 * 6).

Fiquei confuso tanto com a explicação quanto com o código, pois ao testar no PyCharm o código realmente funciona, mas porque nesse caso? O atributo r.area não deveria ser ter sido alterado com os underscores apenas sendo convenções? Pois no meu entenedimento o método iria retornar o valor 7, já que antes de chamarmos o mesmo, fizemos a alteração no valor do atributo r.area... Enfim, alguém me esclarece? Tô injuriado aqui haha

3 respostas
solução!

Olá Gabriel, bom dia, espero que esteja bem!

Os dois underscores (__) antes de um atributo em Python são usados para indicar que o atributo é "name mangling" (ocultação de nome), o que torna o atributo "privado" e dificulta o acesso direto a ele de fora da classe. No entanto, isso não impede que você acesse ou modifique o atributo diretamente; ele apenas torna mais difícil fazer isso.

No seu código, você tem o atributo __area:

self.__area = x * y

Este atributo é privado e, como mencionado, pode ser acessado, mas é considerado uma má prática fazê-lo diretamente. No entanto, o Python permite que você crie um atributo com o mesmo nome fora da classe, como você fez aqui:

r.area = 7

Nesse caso, você não está acessando diretamente o atributo privado __area, mas criando um novo atributo area específico para a instância r. Esse atributo area criado dinamicamente é diferente do atributo privado __area definido na classe.

Quando você chama r.obter_area(), o método obter_area() retorna o valor do atributo privado __area, que não foi alterado quando você criou o atributo area fora da classe. Portanto, o resultado será o valor original calculado durante a inicialização do objeto r (7 * 6), que é 42.

Em resumo, o uso de dois underscores antes de um atributo em Python não impede que você crie atributos com o mesmo nome fora da classe, mas indica uma convenção de que o atributo é privado e deve ser acessado apenas por métodos da classe. No entanto, o Python permite que você acesse o atributo diretamente, se desejar, mas não é considerado uma boa prática fazê-lo.

  • "O desconhecido é onde começam todas as possibilidades." - Capitão Jonathan Archer

Gabriel bom dia!

Sua dúvida é muito pertinente, eu já tive essa dúvida antes.

O que confunde ai é que apesar do nome parecido são variáveis diferentes, veja meu print:

O valor de "area" é 7 e o valor de "__area " é 42

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

Gostei muito das duas explicações, extremamente esclarecedoras, muito obrigado a vocês dois ☺️