Python class attribute encapsulation and access control tutorial
Friends who are new to Python oop (OOP) will most likely have stepped on these two pitfalls:
- Added attributes
__The prefix was thought to be "locked", but it turned out that it could still be read and written in another way; - Assign values to instance attributes externally (for example, change student scores to
-10or200), the logic collapses and the source cannot be found.
This is the problem of insufficient encapsulation - today we will use Python's naming conventions and tools to make the access control of class attributes clear.
1. First understand: what is real encapsulation?
Among the three major features of OOP (encapsulation, inheritance, polymorphism), encapsulation is the foundation. Its core is not to hide attributes completely, but to:
- Bind data and data manipulation methods in a class;
- Hide internal implementation details from the outside (such as what variable names are used to store scores);
- Only expose secure, controlled access (for example, you can only change the score to 0-100).
Python has nothing like Java/C++public、protected、privateKeywords, but through naming convention and syntax sugar, similar effects can be achieved.
2. Python’s three “access control levels”
The following are conventional rules. Except for double underscores, which will be done by the compiler, Python itself will not forcibly intercept any access - after all, this is a "we are all adults" language.
2.1 Public members (Public)
By default, all properties/methods are public and can be used freely inside, outside, and subclasses.
2.2 Protected members (Protected)
Start with **single underscore_The members starting with ** are by convention internal members for themselves and subclasses, and it is best not to touch them from the outside.
But Python will not stop you - if you insist on accessing the code, you will still run, but other people in the team will think you are "ignorant".
2.3 Private members (Private)
Start with ** double underline__For members that begin with and do not end with a double underscore, the Python compiler will automatically do Name Mangling and become_ClassName__varformat. Ostensibly not directly accessible from the outside.
3. Fake lock turns into real door: achieving controlled encapsulation
Although double underscores cannot prevent malicious people, with accessors (getters/setters), it can become a real "security door" - we can add logic such as parameter verification, logging, and permission checking to the door.
3.1 Traditional method: explicitly write getter/setter
Early Python or developers accustomed to Java/C++ will write like this:
However, this way of writing is not Pythonic enough - you have to write it when callings.get_name(), rather than the more naturals.name。
3.2 Recommended method: use@propertyDecorator
Python provides@propertyThis syntactic sugar can "disguise" methods as attributes, retaining security verification while having concise calls like public attributes.
External calls are now very natural:
4. Revealing the name rewriting: Why can the "fake lock" be opened?
Double-underlined members only have their names rewritten, not really hidden. usedir()You can find clues by looking at the instance properties:__namebecame_Student__name。
- Violation of the encapsulation contract;
- Once the class name changes, the rewritten name will also change accordingly, and the code will crash immediately;
- Other developers’ blood pressure will soar when they see it.
5. Don’t get confused: special variable names
There is also a variable/method that starts with a double underscore and ends with a double underscore, such as__init__、__len__、__dict__. This is Python's magic method/property that will not be rewritten by name and can be accessed directly.
6. Hands-on practice: Encapsulationgenderproperty
Let’s do a small exercise and ask for:
- put
genderSet as private property; - Can only be initialized to
'male'or'female'; - Subsequent modifications can only be made to these two values;
- use
@propertyaccomplish.
Reference implementation
7. Summary of best practices
- Private by default, exposed on demand: Unless it is determined that the attribute is "completely public and does not require verification", otherwise add it
__prefix; - **use
@propertyReplaces explicit getters/setters: more Pythonic and more natural to call; - Setter must be verified: This is one of the core values of encapsulation, don’t just do simple assignment;
- Single underline is only used for internal agreements: such as tool methods and properties that you do not want to make public for the time being;
- Don’t touch the variable with the rewritten name: If you touch it, you will dig a hole for yourself and the team;
- Properly design read-only/read-write attributes: Attributes such as name and ID number generally only leave
@property, do not add@xxx.setter。
Good encapsulation can make the code more robust (to prevent external misoperations), easier to maintain (if the internal implementation is changed, external calls will be insensitive), and easier to expand (permission checks and logging will be added in the future, just change it directly in the setter). Hurry up and try it in your project!

