Using access modifiers is part of the daily job of any OOP developer but things are a bit complex in python ... or maybe a bit simpler.
Let’s Make it simple:
Does python have any access modifiers?
The short answer is no. (But in the long answer we will see there are some conventions.)
Absolutely not.
Before any further questions, let’s dive into the long answer as it may answer many more questions.
First of all, let’s define access modifiers. According to Wikipedia:
“Access modifiers are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.”
In other words, public variables are expected to be accessible in all classes (at least in the same package or module). Protected variables are expected to be accessible by the subclasses, and private variables, not by any other classes.
In essence, access modifiers are about information hiding. But python is shaped around the philosophy of “We are all consenting adults here.” so there is no information hiding! But there are some conventions as I said earlier.
Imagine there are conventions that every developer follows, but if they ever needed they can access all the information they want (private and protected variables and methods), as you can imagine it is so useful especially for debugging and serialization.
Well there are some conventions and they are so simple:
__init__
for constructor or __str__
for parse to string. )Let’s see some code, imagine we have a class named MyClass with 3 variables:
class MyClass:
public_v = 'it is public'
_protected_v = 'it is protected'
__private_v = 'it is private'
By convention, an instance of Person just can use
public_v
but let’s see what happened if we call other variables:>>>c = MyClass()
>>>c.public_v
"it is publi"
>>>MyClass.public_v
"it is public"
>>>c._protected_v
"it is protected"
>>>MyClass._protected_v
"it is protected"
>>>c.__private_v
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute '__private_v'
Oh look like we have a private variable, no don’t let this simple trick fool you, as I said there is no such thing as information hiding in python, this is “name mangling” that I earlier told you about.
When we use it (i.e. start the name of the variable with double-underscore), the interpreter will change the variable actual name to “
_ClassName__VariableName
” so if anyone outside of the class (MyClass
) calls it by “__VariableName
” they will get an AttributeError
, but:>>>p._MyClass__private_v
"it is private"
>>>MyClass._MyClass__private_v
"it is private"
Now you can see it is accessible. As Luciano Ramalho said in his famous book “Fluent Python”:
“Name mangling” is about safety, not security: it’s designed to prevent accidental access and not intentional wrongdoing.”
And by the way, there are some pythonistas that are not happy with “name mangling”.
“Never, ever use two leading underscores. This is annoyingly private. If name clashes are a concern, use explicit name mangling instead (e.g.,
). This is essentially the same thing as double-underscore, only it’s transparent where double underscore obscures."_MyThing_blahblah
- Ian Bicking
But anyway there is name mangling and it’s pretty common between pythonistas; you can use either of them and everyone will get it, remember it’s just convention, so the choice is on you.
So in summary, python access modifiers are just conventions. In short, for protected variable use an underscore in the beginning of the variable name (
_variable
) and for private use double-underscore or as it is called name mangling(__variable
). And remember for private access modifier you can use another convention too, underscore class name underscore variable name (_class_variable
)References: