Problem scenario
You see two underscores or two underbars before a function in Python. What does this syntax signify?
Possible Solution #1
The answer is best explained by running this program once with no modification and a second time with a modification.
class ContintClass():
def __init__(self):
self.__completelyprivate = "1111111111"
self._semiprivate = "2222222"
foo = ContintClass()
#print(foo.__completelyprivate)
print("Above is an attempt to print a completely private data member of an object")
print("Below is an attempt to print a semi-private data member of an object")
print(foo._semiprivate)
Before you run the program the second time, uncomment out the line "print(foo.__completelyprivate)" by removing the "#". The first time you will see this:
Above is an attempt to print a completely private data member of an object
Below is an attempt to print a semi-private data member of an object
2222222
The second time you run the program (after you uncomment out that line), you will see this:
Traceback (most recent call last):
File "foobar.py", line 8, in
print(foo.__completelyprivate)
AttributeError: 'ContintClass' object has no attribute '__completelyprivate'
Two underscores refer to an object that is completely private. One or fewer underscores relating to a class will make the data member accessible outside of the class via the function itself. Two or more underscores in a data member's variable name of a class will make the data member never be accessible outside of the class via the function itself.
According to Expert Python Programming (on page 191), "[n]o user-defined method should use this convention unless it explicitly has to implement one of the Python object protocols."
Possible Solution #2
When the __
appears in the __init__
, the underscores are part of a reserved word. To instantiate a class, or to create an object in a Python class, the __init__
word must be present. If you try a different word (unlike the use of self in object-oriented programming in Python), it will not work. The underscores are necessary; you can try it for yourself by modifying the above program's __init__
keyword.
Possible Solution #3
It could refer to __init__.py
. This is a reference to a package in Python called a "namespace package" (as contradistinguished from a regular package). These packages are composed of smaller packages. To learn more about this, see this external link or this one.
Possible Solution #4
Every module in Python has a "built-in __name__ variable." When the program is run by itself, the variable is "__main__". But when the program is invoked via an "import" statement of a different program, the "__name__" variable is not "__main__".
(These above three sentences are quoted and paraphrased from page 84 of Programming in Python.)
Possible Solution #5
The term dunders is a portmanteau of "double underscores". This syntax denotes a magic method in Python (with two prefix and two suffix underbars). To read more, see https://www.geeksforgeeks.org/dunder-magic-methods-python/ or https://www.python.org/dev/peps/pep-0008/#module-level-dunder-names According to Expert Python Programming (page 191) the term to describe this syntax is "special methods" (with the term "dunder methods" being obsolete); the 4th edition can be found here.