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

Dúvida em atributos "privados" python.

Fiz os cursos de formação em python e fiquei em dúvida qual convenção usar para um atributo privado?

Dois underscore --> __atributo ou um underscore --> _atributo

2 respostas
solução!

Oi Wellington, como você está? Espero que esteja bem ^-^

Segundo a documentação da linguagem, a convenção é um único underscore(_atributo). Abaixo, um pequeno trecho da documentação:

"Variáveis de instância “privadas”, que não podem ser acessadas, ​​exceto em métodos do próprio objeto, não existem em Python. No entanto, existe uma convenção que é seguida pela maioria dos programas em Python: um nome prefixado com um sublinhado (por exemplo: _spam )"

E qual a diferença em usar um underscore ao invés de dois?

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 __variavel será substituído por _nomedaclasse__variavel. Vamos ver um exemplo em código para ficar mais claro, tá?

  • Imagine a seguinte classe Animal:
class Animal:
    def __init__(self):
        self.__cachorro = "Bob"
        self._gato = "Mimi"

Agora, vamos confirmar que o Python realmente modifica o atributo com o duplo underscore e podemos fazer isso imprimindo todos os atributos e métodos daquele objeto através do comando dir, veja:

objeto_animal = Animal()
print(dir(objeto_animal))

Como saída teremos:

['_Animal__cachorro', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', '_gato']

Observe que temos _Animal__cachorro na listagem, que se refere a variável __cachorro modificada, pois ela estava com o duplo underscore. Se tentarmos acessar diretamente o atributo __cachorro não iremos conseguir, dará erro de atributo dizendo que a classe Animal não possui o atributo __cachorro e isso ocorre porque internamente o Python modificou esse atributo para a nomenclatura que foi mostrada: _Animal__cachorro:

>> print(objeto_animal.__cachorro)
>> AttributeError: 'Animal' object has no attribute '__cachorro'

Agora, se tentarmos acessar o atributo com um único underscore iremos conseguir tranquilamente, veja:

>> print(objeto_animal._gato)
>> Mimi

Podemos também acessar o atributo com o duplo underscore, mas é necessário o conhecimento de saber que o Python irá modificar esse atributo pelo fato de estar com o duplo underscore. Em código fica algo como:

>> print(objeto_animal._Animal__cachorro)
>> Bob

Talvez fui além do que você perguntou, mas a ideia é que você saiba que em Python não existe atributo 100% privado, sempre teremos como acessá-lo, a convenção é apenas para que outros programadores saibam que há uma norma a seguir e que não é interessante acessar aquele atributo fora da classe. Tudo bem?!

Welligton, se tiver ficado alguma dúvida é só falar, estou por aqui, tá bom?

Abraços!

Muito obrigado! Já entendi.