Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Atributos Privados na Herança

Olá, surgiu uma dúvida em relação a Herança ao utilizar os atributos privados, em qual a melhor maneira a se utilizar ou por convenção qual é a utilizada:

Quando utilizo os dois underscores ( __ ) para criar atributos "privados" e crio as properties para acessá-los, consegue-se normalmente acessá-los através das classes filhas, somente chamando o nome do atributo:

class Program:

    def __init__(self, name, year):
        self.__name = name
        self.year = year
        self.__likes = 0

    @property
    def name(self):
        return self.__name

    def dar_like(self):
        self.__likes += 1

    @property
    def likes(self):
        return self.__likes


class Film(Program):

    def __init__(self, name, year, duration):
        super().__init__(name, year)
        self.duration = duration

        print(self.likes)

Porém, no curso é ensinado a utilizar somente um undescore. E, utilizando somente um underscore, não é necessário criar as properties para acessar os atributos diretamente.

Então, há alguma diferença em qual utilizar ou é somente uma convenção utilizar um único underscore e colocar as properties para acessar os atributos "mais bonitinho", sem o undescore?

1 resposta
solução!

Olá Thiago, tudo bem com você?

Peço desculpas pela demora no retorno.

Segundo a documentação do Python por convenção trabalharemos com um underscore (_atributo). O uso do underscore serve para informar que esse atributo é privado, mas devemos ter em mente que no Python não existem atributos 100% privados, que são impossíveis de serem acessados. Existe sim a criação de mecanismos que tornem o acesso mais verboso ou que sinalize para os(as) programadores(as) que determinado atributo não deve ser acessado fora da classe.

Sobre a diferença entre o uso de um ou dois underscore temos o seguinte.

Duplo Underscore

Quando utilizamos o duplo underscore acontece um fenômeno chamado de name mangling que se refere ao Python modificar o nome do atributo para dificultar o seu acesso direto e também, para evitar conflitos de nomes em subclasses, então qualquer variável dentro da classe no formato __atributo será substituído por _classe__atributo.

Para acessarmos um atributo declarado com privado com o uso de dois underscore podemos transpor o name mangling, apresentado a seguir, não sendo uma forma elegante ou Pythonica.

filme = Film('Rei Leão', 1994, 86)
filme.dar_like()
filme.dar_like()
filme.dar_like()
print(filme._Program__likes)

Resultado

3

Simple underscore

Já com o uso de apenas um underscore (_atributo) não ocorre o name mangling, mudando o nome do atributo internamente, assim podemos acessá-lo diretamente.

filme = Film('Rei Leão', 2012, 150)
filme.dar_like()
filme.dar_like()
filme.dar_like()
print(filme._likes)

Resultado

3

Note que o acesso ao atributo foi possível nos dois casos mas para que ele possa acontecer de uma forma Pythonica, devemos recorrer ao uso do decorator @property, permitindo a criação de métodos que irão retornar os atributos privados, e a chamada desses métodos serão realizadas utilizando a mesma sintaxe de quando chamamos um atributo. Como demonstrado a seguir:

filme = Film('Rei Leão', 2012, 150)
filme.dar_like()
filme.dar_like()
filme.dar_like()
print(filme.likes)

Resultado

3

Em resumo temos que no Python não existe atributos 100% privados existe uma convenção de que atributos que iniciam com simples ou duplo underscore não devem ser acessados diretamente fora da classe. No caso de duplo underscore temos a nosso favor o uso do name mangling que proporciona mais uma barreira de segurança contra o acesso direto de um atributo.

Para entender mais sobre atributos, métodos privados e até mesmo sobre name mangling, recomendo a leitura dos seguintes artigos que estão em inglês, caso tenha dificuldade com o idioma, recomendo o uso do tradutor do navegador.

Em caso de dúvidas, encontro-me à disposição.

Abraços e bons estudos.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!