De forma muito didática o instrutor apresentou o conceito de uso de atributo de classe de visibilidade Protegida "atributo" como sendo visibilidade Privada " _ atributo".
Na prática ele ensinou a usar de fato o conceito de visibilidade Protegida mas mensionou o tempo todo como "Privada" o que gera confusão no aprendizado do aluno.
Visibilidade Protegida (Convencional)
Atributos e métodos protegidos são indicados por um único sublinhado (_) no início do nome. Eles não são realmente inacessíveis, mas a convenção é que você não deve acessá-los diretamente fora da classe ou de suas subclasses. É um aviso para outros desenvolvedores de que o atributo faz parte da "lógica interna" da classe.
Características:
Nome: _nome_do_atributo ou _nome_do_metodo.
Acesso: Tecnicamente, você pode acessá-lo (ex: objeto._nome_do_atributo), mas isso é considerado uma má prática.
Uso: Geralmente, são usados para atributos ou métodos que devem ser acessados apenas pela própria classe ou por classes que a herdam.
Exemplo:
Python
class Animal:
def init(self, nome):
self._nome = nome # Atributo protegido (por convenção)
def _fazer_barulho(self): # Método protegido
print("Som de animal")
class Cachorro(Animal):
def latir(self):
print(f"{self._nome} está latindo.") # Acesso permitido dentro da subclasse
meu_cachorro = Cachorro("Buddy")
meu_cachorro.latir()
Acesso "externo", embora possível, é desaconselhado
print(meu_cachorro._nome)
Visibilidade Privada (Ocultação de Nome)
Atributos e métodos privados são indicados por dois sublinhados (__) no início do nome. Python faz um processo chamado "name mangling" (ou "ocultação de nome") para tornar o acesso a esses atributos mais difícil. O nome é alterado para _NomeDaClasse__nome_do_atributo.
Características:
Nome: __nome_do_atributo ou __nome_do_metodo.
Acesso: Não podem ser acessados diretamente fora da classe. Tentativas de acesso direto resultam em um AttributeError.
Uso: São usados para atributos ou métodos que são estritamente de uso interno da classe e não devem ser acessados por subclasses ou outras partes do programa.
Exemplo:
Python
class ContaBancaria:
def init(self, saldo_inicial):
self.__saldo = saldo_inicial # Atributo privado
def depositar(self, valor):
self.__saldo += valor
print(f"Novo saldo: {self.__saldo}")
def __verificar_senha(self): # Método privado
print("Verificando senha...")
minha_conta = ContaBancaria(100)
Erro: AttributeError
print(minha_conta.__saldo)
Acesso indireto através do método público
minha_conta.depositar(50)