Atributos privados do Python

Resumo : neste tutorial, você aprenderá sobre encapsulamento e como usar atributos privados para realizar o encapsulamento em Python.

Introdução ao encapsulamento em Python

O encapsulamento é um dos quatro conceitos fundamentais da programação orientada a objetos, incluindo abstração, encapsulamento, herança e polimorfismo.

Encapsulamento é o empacotamento de dados e funções que funcionam nesses dados em um único objeto. Ao fazer isso, você pode ocultar o estado interno do objeto do lado de fora. Isso é conhecido como ocultação de informações .

Uma classe é um exemplo de encapsulamento. Uma classe agrupa dados e métodos em uma única unidade. E uma classe fornece acesso aos seus atributos por meio de métodos.

A ideia de ocultar informações é que se você tiver um atributo que não é visível para o exterior, você pode controlar o acesso ao seu valor para garantir que seu objeto sempre tenha um estado válido.

Vamos dar uma olhada em um exemplo para entender melhor o conceito de encapsulamento.

Exemplo de encapsulamento Python

O seguinte define a Counterclasse:

class Counter:
    def __init__(self):
        self.current = 0

    def increment(self):
        self.current += 1

    def value(self):
        return self.current

    def reset(self):
        self.current = 0
Linguagem de código:  Python  ( python )

A Counterclasse tem um atributo chamado currentcujo padrão é zero. E tem três métodos:

  • increment()aumenta o valor do currentatributo em um.
  • value()retorna o valor atual do currentatributo
  • reset()define o valor do currentatributo como zero.

O seguinte cria uma nova instância da Counterclasse e chama o increment()método três vezes antes de mostrar o valor atual do contador na tela:

counter = Counter()


counter.increment()
counter.increment()
counter.increment()

print(counter.value())
Linguagem de código:  Python  ( python )

Saída:

3Linguagem de código:  Python  ( python )

Funciona perfeitamente bem, mas tem um problema.

Do lado de fora da Counterclasse, você ainda pode acessar o atributo atual e alterá-lo para o que quiser. Por exemplo:

counter = Counter()

counter.increment()
counter.increment()
counter.current = -999

print(counter.value())
Linguagem de código:  Python  ( python )

Saída:

-999Linguagem de código:  Python  ( python )

Neste exemplo, criamos uma instância da Counterclasse, chamamos o increment()método duas vezes e definimos o valor do atributo atual como um valor inválido -999.

Então, como você evita que o currentatributo seja modificado fora da Counterclasse?

É por isso que os atributos privados entram em jogo.

Atributos privados

Atributos privados só podem ser acessíveis a partir dos métodos da classe. Em outras palavras, eles não podem ser acessíveis de fora da classe.

Python não possui um conceito de atributos privados. Em outras palavras, todos os atributos são acessíveis de fora de uma classe.

Por convenção, você pode definir um atributo privado prefixando um único sublinhado (_):

_attribute

Isso significa que o _attribute não deve ser manipulado e pode sofrer alterações significativas no futuro.

O seguinte redefine a Counterclasse com o currentatributo privado por convenção:

class Counter:
    def __init__(self):
        self._current = 0

    def increment(self):
        self._current += 1

    def value(self):
        return self._current

    def reset(self):
        self._current = 0
Linguagem de código:  Python  ( python )

Mangling nome com sublinhados duplos

Se você prefixar um nome de atributo com sublinhados duplos ( __) assim:

__attribute

Python mudará automaticamente o nome do __attributepara:

_class__attribute

Isso é chamado de mangling em Python.

Ao fazer isso, você não pode acessar o __attribute diretamente de fora de uma classe como:

instance.__attributeLinguagem de código:  CSS  ( css )

No entanto, você ainda pode acessá-lo usando o nome _class__attribute:

instance._class__attributeLinguagem de código:  CSS  ( css )

O exemplo a seguir redefine a classe Counter com o atributo __current:

class Counter:
    def __init__(self):
        self.__current = 0

    def increment(self):
        self.__current += 1

    def value(self):
        return self.__current

    def reset(self):
        self.__current = 0


Agora, se você tentar acessar o atributo __current, receberá um erro:

counter = Counter()
print(counter.__current)Linguagem de código:  PHP  ( php )

Saída:

AttributeError: 'Counter' object has no attribute '__current'Linguagem de código:  JavaScript  ( javascript )

No entanto, você pode acessar o atributo __current como _Counter___current assim:

counter = Counter()
print(counter._Counter__current)Linguagem de código:  PHP  ( php )

Resumo

  • Encapsulamento é o empacotamento de dados e métodos em uma classe para que você possa ocultar as informações e restringir o acesso externo.
  • Prefixe um atributo com um único sublinhado ( _) para torná-lo privado por convenção.
  • Prefixe um atributo com sublinhados duplos ( __) para usar o nome mangling.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *