📜 ⬆️ ⬇️

Python 3 Encapsulation

image


Definition


The meaning of the term “encapsulation” is vague and differs from source to source. It is generally accepted that encapsulation is one of the fundamental principles of OOP, although some scientific articles completely omit encapsulation from the list. For example, John Mitchell in the book "Concepts in programming languages" when enumerating the main concepts in the PLO mentions only abstraction - a term which is considered to be close to encapsulation in meaning, but still more extensive and high-level. On the other hand, Robert Martin in his book “Pure Architecture” clearly indicates that encapsulation, inheritance and polymorphism is considered the foundation of the PLO.


The variety of definitions given to the term “encapsulation” is difficult to bring to a common denominator. In general, there are two approaches to the meaning of this term. Encapsulation can be viewed as:



Encapsulation as a link


This kind of interpretation of the term "encapsulation" is very simple to explain. In this case, any class in which there is at least one variable and one method that controls it clearly demonstrates this principle.


#!/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" ) 

The “Phone” class combines the data in the “number” variable with the “print_number ()” method


You can create a class that consists only of methods (and does not contain variables), which can be convenient in some programming languages. It is also possible to create a class containing only data, without methods, which, in many cases, should be avoided. Both practices should be applied when necessary, and their relationship to “unifying” encapsulation is debatable.


Encapsulation as access control


Explaining the concept of restricting access to data or methods requires much more detail. First of all, in this context, the term “access” should be understood as the ability to see and / or change the internal contents of a class. There are several levels of access provided by most OOP languages. Summarizing we can say that the object data can be:



Most languages ​​have additional access levels that lie between these boundaries. For example, in C ++ and Python3 there are three levels of access: public, secure, and private; C # adds the keyword "internal" to the list.


It should be noted that in most programming languages, the level of access to any data is set by default. For example, in C ++, the default data access level in a class is set as private — only class members and friends can access its data. The standard level of access to a structure ( struct ) in C ++ is different - it is public, and data in such a structure can be accessed by anyone. The level of access for class variables and methods in Python 3 is entirely dependent on syntax.


Examples


Encapsulation


Python 3 provides 3 levels of data access:



For brevity and simplicity, only two basic levels (private and public) are covered in the example.


 #!/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" ) 

Access to public variables and methods can be obtained from the main program. Attempting to get private data or run a private method will result in an error.


Encapsulation violation


The language itself provides the programmer with a syntactic tool that can bypass encapsulation. Reading and modifying private variables and calling private functions is still possible.


 #!/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" ) 

A few words about magic


There are methods, so-called “magic methods” (“magic methods”) or “special methods” (“special methods”), which allow classes to define their behavior with respect to standard language operators. The following expressions can serve as an example of such language operators:



Python 3 supports many of these methods; a full list can be found on the official language documentation page. __init__ (initializer) is the most frequently used one and is launched when creating a new class object. The other, __lt__ (extended comparison), defines rules for comparing two objects of a custom class. Such methods do not fall into the category of “private” or “public”, since they serve other purposes and are deeply rooted in the internal structure of the language.


 #!/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" ) 

Magic methods can be invoked by any user in the same way as any public method in Python, however they are intended for implicit use in their particular cases. A special case for the __init__ method is the initialization of a new class object. __lt__ serves to compare two objects.


Conclusion


Python3 does not provide limited access to any class variable or method. Data that should be hidden can actually be read and modified. In Python3, encapsulation is more of a convention, and the programmer must take care of saving it on its own.


Sources


  1. John C. Mitchell, Concepts in programming languages
  2. Robert C. Martin, Clean Architecture, A Guide to Software Structure and Design

')

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


All Articles