Encapsulation in Python 3Kateryna BondarenkoBlockedUnblockFollowFollowingMar 5DefinitionThe definition of encapsulation is vague, and it differs dramatically from source to source.
It is generally agreed that encapsulation is one of the fundamental OOP principles, however, several definitions of them omit encapsulation completely.
For example, John C.
Mitchell in his Concepts in programming languages states that main OOP language concepts are dynamic lookup, subtyping, inheritance, and abstraction, which is close to encapsulation by meaning, but is generally seen as more broad and high-level concept.
On the other hand, Robert C.
Martin in his Clean Architecture, A Craftsman’s Guide to Software Structure and Design clearly states that encapsulation, inheritance, and polymorphism are seen as fundamentals in OOP.
Trying to condense different definitions of the same concept to one generally accepted description proves to be even more problematic.
There are two main approach to the term.
Encapsulation can be seen as:bundling of data with methods operating on that data;a set of tools which can restrict access to data or methods that can manipulate it.
Encapsulation as BundlingInterpretation of encapsulation as bundling data with its methods is a easy to work with.
In this case, any meaningful class with at least one variable and one method is a clear demonstration of this principle.
Class ‘Phone’ connects data stored in variable 'number’ and method 'print_number()’It is possible to create a class that consists only of methods (and no variables), which might be handy in some programming languages.
It is also possible to create class with no methods and only data stored in it, which, most likely, is a bad practice and should be avoided.
Anyway, both practices should be applied only if necessary and their connection to ‘bundling’ encapsulation is disputable.
Encapsulation as Access restrictionThe concept of restricting access to data or methods requires far more details.
First of all, in this context, the term ‘access’ should be understood as ability to see and/or modify some internal content of a class.
There are several access levels provided by most OOP languages.
Generally speaking, the object’s data can be:public — visible and modifiable by all;private — visible and modifiable only by object/class.
Majority of languages declare additional grades of accessibility all of which fall between those boundaries.
For example, C++ and Python 3 have three levels: public, protected, and private; C# adds internal to the list.
It is worth to mention that access level to any data chunk is set to some default value by programming language.
For example, in C++ the default access level to a class instance is set to private — its data can be accessed only by members and friends of a class.
Default value for a struct in C++ differs — it is set to public and data in such struct can be accessed by anyone.
Default access level for class variables and methods in Python 3 fully rely on syntax details.
ExamplesEncapsulationPython 3 provides programmer with 3 access levels:public (no special syntax, publicBanana);protected (one underscore at the beginning, _protectedBanana);private (two underscores at the beginning, __privateBanana).
To keep the example short and simple, only two basic levels (private and public) are demonstrated.
Public variables and methods can be accessed from the main program.
Attempt to gain private data or run private method will produce an error:my_phone.
__turn_on()print( “Turned on: “, my_phone.
__how_many_times_turned_on)print( “Turned on: “, my_phone.
how_many_times_turned_on)Breaking encapsulationHowever, the language itself provides the programmer with a tool that can bypass the encapsulation.
It is possible to read and modify private variables and call private functions.
Few words about MagicThere are methods, so-called ‘magic methods’ or ‘special methods’, which allow classes to define their own behavior with respect to language operators.
The following expressions can serve as examples of such language operators:x > yx[ i ]Python 3 supports a great variety of such methods; the full list can be easily found on the official documentation webpage.
The __init__ (inititalizer) is the most used of them, and is run implicitly when new instance of a class is being created.
Another one, __lt__ (rich comparison), defines how to compare two objects of custom class.
Such methods do not fall into ‘public’ or ‘private’ category since they serve different purpose and go deep to the language internals.
Magic methods can be called by anyone as any public method in Python, however, they are meant to be implicitly used in their own special cases.
Special case for __init__ method would be an initialization of new instance.
The use of __lt__ is a comparison of two instances.
ConclusionPython 3 does not enforce privacy of any variables or methods.
Things that are meant to have access restrictions are not truly hidden and can be easily seen or modified.
In Python 3, encapsulation as data hiding is mostly conventional.
It is up to programmer to ensure that data with access restrictions stays hidden.
.. More details