Python Access Modifiers: Public, Private, and Protected Variables

Written by kianooshsanatkar | Published 2021/04/16
Tech Story Tags: python | patterns | programming | coding | access-modifiers-in-python | access-modifiers | python-programming | learn-python

TLDR Python Access Modifiers: Public, Private, and Protected Variables are keywords in object-oriented languages that set accessibility of classes, methods, and other members. 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. Don’t touch or call anything that starts with ‘_’ in an instance of a class. Use a double-underscore ‘__’ for private variables, this convention is called “name mangling”via the TL;DR App

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.)

Is this a drawback of Python?

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:
  1. Don’t touch or call anything that starts with ‘_’ in an instance of a class.
    By convention, anything that starts with underscore ‘_’ is implementation detail.
  2. Use a single underscore ‘_’ for protected variables.
  3. Use a double-underscore ‘__’ for private variables, this convention is called “name mangling”. We will talk about it in a minute.
  4. Don’t create any new dunder methods. In another word, don’t create methods or variables that start with double-underscore and end with double-underscore like ‘__method__’ these are special methods(called dunder methods), and we implement them for special cases (e.g.
    __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.,
_MyThing_blahblah
). This is essentially the same thing as double-underscore, only it’s transparent where double underscore obscures."

- 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.

Summary

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:

Written by kianooshsanatkar | Just an enthusiastic geek 🤓 who loves nature, science, and developing software 🤘🤘
Published by HackerNoon on 2021/04/16