Encapsulamento em Python 3

imagem


Definição de


O significado do termo "encapsulamento" é vago e difere de fonte para fonte. É geralmente aceito que o encapsulamento é um dos princípios fundamentais da OOP, embora alguns artigos científicos omitam completamente o encapsulamento da lista. Por exemplo, John Mitchell no livro “Concepts in Programming Languages”, ao listar os principais conceitos em OOP, menciona apenas abstração - um termo que é considerado próximo do encapsulamento por significado, mas ainda mais extenso e de nível superior. Por outro lado, Robert Martin, em seu livro Pure Architecture, afirma explicitamente que o encapsulamento, a herança e o polimorfismo são considerados a base da OOP.


A variedade de definições dadas ao termo "encapsulamento" é difícil de trazer para um denominador comum. Em geral, duas abordagens para o significado desse termo podem ser distinguidas. O encapsulamento pode ser considerado como:


  • comunicação de dados com métodos que controlam esses dados;
  • Um conjunto de ferramentas para controlar o acesso a dados ou métodos que gerenciam esses dados.

Encapsulamento como uma conexão


Esse tipo de interpretação do termo "encapsulamento" é muito fácil de explicar. Nesse caso, qualquer classe na qual exista pelo menos uma variável e um método que a controla demonstram claramente esse princípio.


#!/usr/bin/python3 class Phone: number = "111-11-11" def print_number(self): print( "Phone number is: ", self.number ) my_phone = Phone() my_phone.print_number() input( "Press Enter to exit" ) 

A classe Phone combina os dados no número da variável com o método print_number ()


Você pode criar uma classe que consiste apenas em métodos (e não contém variáveis), o que pode ser conveniente em algumas linguagens de programação. Também é possível criar uma classe contendo apenas dados, sem métodos, os quais, em muitos casos, devem ser evitados. Ambas as práticas devem ser aplicadas quando necessário, e sua relação com o encapsulamento "unificador" é discutível.


Encapsulamento como controle de acesso


Explicar o conceito de restrição de acesso a dados ou métodos requer muito mais detalhes. Antes de tudo, neste contexto, o termo "acesso" deve ser entendido como a capacidade de ver e / ou modificar o conteúdo interno de uma classe. Existem vários níveis de acesso fornecidos pela maioria dos idiomas OOP. Resumindo, podemos dizer que os dados do objeto podem ser:


  • público ( public ) - os dados estão disponíveis para todos;
  • privado ( private ) - os dados estão disponíveis apenas para o objeto / classe a que pertencem.

A maioria dos idiomas possui graus adicionais de acesso que estão entre esses limites. Por exemplo, em C ++ e Python3, existem três níveis de acesso: público, protegido e privado; C # adiciona a palavra-chave "interno" à lista.


É importante notar que na maioria das linguagens de programação, o nível de acesso a qualquer dado é definido por padrão. Por exemplo, em C ++, por padrão, o nível de acesso aos dados em uma classe é definido como privado - apenas membros e amigos da classe podem acessar seus dados. O nível padrão de acesso à estrutura ( struct ) no C ++ é diferente - é público, e os dados dessa estrutura podem ser acessíveis a qualquer pessoa. O nível de acesso para variáveis ​​e métodos de classe no Python 3 depende completamente da sintaxe.


Exemplos


Encapsulamento


O Python 3 fornece três níveis de acesso a dados:


  • public ( public , nenhuma sintaxe especial, publicBanana );
  • protected ( protected , um sublinhado no início do nome, _protectedBanana );
  • private ( private , dois sublinhados no início do nome, __privateBanana ).

Por questões de brevidade e simplicidade, apenas dois níveis básicos (privado e público) são destacados no exemplo.


 #!/usr/bin/python3 class Phone: username = "Kate" # public variable __how_many_times_turned_on = 0 # private variable def call(self): # public method print( "Ring-ring!" ) def __turn_on(self): # private method self.__how_many_times_turned_on += 1 print( "Times was turned on: ", self.__how_many_times_turned_on ) my_phone = Phone() my_phone.call() print( "The username is ", my_phone.username ) # my_phone.turn_on() # my_phone.__turn_on() # print( “Turned on: “, my_phone.__how_many_times_turned_on) # print( “Turned on: “, my_phone.how_many_times_turned_on) # will produce an error input( "Press Enter to exit" ) 

O acesso a variáveis ​​e métodos públicos pode ser obtido no programa principal. Tentar recuperar dados privados ou executar um método privado resultará em um erro.


Violação de encapsulamento


A própria linguagem fornece ao programador uma ferramenta de sintaxe que pode contornar o encapsulamento. Ainda é possível ler e modificar variáveis ​​privadas e chamar funções privadas.


 #!/usr/bin/python3 class Phone: username = "Kate" # public variable __serial_number = "11.22.33" # private variable __how_many_times_turned_on = 0 # private variable def call(self): # public method print( "Ring-ring!" ) def __turn_on(self): # private method self.__how_many_times_turned_on += 1 print( "Times was turned on: ", self.__how_many_times_turned_on ) my_phone = Phone() my_phone._Phone__turn_on() my_phone._Phone__serial_number = "44.55.66" print( "New serial number is ", my_phone._Phone__serial_number ) input( "Press Enter to exit" ) 

Algumas palavras sobre Magic


Existem métodos, os chamados "métodos mágicos" ou "métodos especiais", que permitem às classes determinar seu comportamento em relação aos operadores de linguagem padrão. As seguintes expressões podem servir como um exemplo desses operadores de idioma:


  • x > y
  • x[ i ]

O Python 3 suporta muitos desses métodos. Uma lista completa pode ser encontrada na página de documentação oficial do idioma. __init__ (inicializador) é o mais usado deles e inicia quando um novo objeto de classe é criado. O outro, __lt__ (comparação avançada), define regras para comparar dois objetos de uma classe de usuário. Tais métodos não se enquadram na categoria de "privado" ou "público", pois servem a outros propósitos e estão profundamente enraizados na estrutura interna da linguagem.


 #!/usr/bin/python3 class Phone: def __init__(self, number): # magic method / inititalizer print( "The Phone object was created" ) self.number = number def __lt__(self, other): # magic method / rich comparison return self.number < other.number my_phone = Phone(20) other_phone = Phone(30) if my_phone < other_phone: print( "Two instances of custom class were compared" ) print( "'__lt__' was called implicitly" ) if my_phone.__lt__(other_phone): print( "Now, '__lt__' was used explicitly" ) input( "Press Enter to exit" ) 

Os métodos mágicos podem ser chamados por qualquer usuário da mesma maneira que qualquer método público no Python, mas eles devem ser usados ​​implicitamente em seus casos especiais. Um caso especial para o método __init__ é a inicialização de um novo objeto de classe. __lt__ é usado para comparar dois objetos.


Conclusão


O Python3 não fornece acesso limitado a nenhuma variável ou método de classe. Os dados que devem estar ocultos podem, de fato, ser lidos e modificados. No Python3, o encapsulamento é mais uma convenção, e o programador deve cuidar de preservá-lo por conta própria.


Fontes


  1. John C. Mitchell, conceitos em linguagens de programação
  2. Robert C. Martin, Arquitetura Limpa, Um Guia do Artesão para Estrutura e Design de Software

Source: https://habr.com/ru/post/pt444338/


All Articles