Meaning of Underscores ( _ & __ ) in Python Variable Names
Single and Double underscores have special meaning in Python variable and method names. Some of the meaning is by convention and some of it is enforced by Python Interpreter. In this article I’ll only cover the meaning of single and double leading underscores in Python variable names.
Single Leading Underscore ( _single ):
According to PEP8, single leading underscore in variable name is intended for internal use only.
Let’s dive into an example to understand where it is by convention and where it is enforced by Python interpreter.
class Single:
def __init__(self):
self.a = 1
self._b = 2
Let’s create the object of above class and try to access the variable with single leading underscore.
>>> obj = Single()>>> obj.a
1>>> obj._b
2
As you can see from the above output that the single leading underscore is accessible from outside the class so here the meaning of single leading underscore is by convention and not enforced by Python Interpreter.
Now let’s check the following example where it is enforced by Python interpreter.
# file_1.py
a = 1
_b = 2# file_2.py
from file_1 import *
print(a)
# 1print(_b)
# NameError: name '_b' is not defined
Defined one public and one private variable in file_1.py
and tried to access both variables in file_2.py
using wildcard import. This wildcard import didn’t include the private one and that’s why exception is raised when tried to access the single leading underscore variable. So here it is enforced by Python Interpreter.
Double Leading Underscore ( _double ):
The use of double leading underscore with variable is not a convention, it has specific meaning to Python Interpreter.
Python will do name mangling to variables with double leading underscores to avoid the conflicts of names between the main class and its subclasses.
To have better understanding, Let’s dive into following example:
class Double:
def __init__(self):
self.a = 1
self.__b = 2
Now take a look at the attributes on its object using the built-in function dir
:
>>> double = Double()
>>> dir(double)
['_Double__b', ..., 'a']>>> double.a
1>>> double.__b
AttributeError: 'Double' object has no attribute '__b'>>> double._Double__b
2
From above output, you can see self.a
is not changed and behaves the same way. But __b
mangled to Double__id
for avoiding names conflicts with subclasses. So double leading underscores are enforced by Python Interpreter.
The purpose of this article is just to help you to understand the different patterns of leading underscores in Python so you can write a better Pythonic code.
If you have any questions, please feel free to leave a comment below.