Meaning of underscores (_ & __) in Python variable names:
Leading underscores in Python variable names (for example _foo and __foo) protect developers from naming conflicts.
A single underscore in front of a variable name (prefix) is a hint that a variable is meant for internal use only.
A double underscore prefix causes the Python interpreter to rewrite the variable name in order to avoid naming conflicts in subclasses.
Double underscores are also called "dunders" in Python.
EXAMPLE:
========
NOTE:
=====
When we check the attributes on the object dir(t),when we look for foo,_bar,__baz in above
list,we notice that foo and __bar appear same as as it is in class(Nothing Change),
when we notice __baz its _Test__baz (Python Interpretor Does this to prevent the subclasses, name mangling, i.e when Test class is inherited when they want to use the same name)
so
print(t.foo)
print(t._bar)
Prints proper values:
But if we do:
print(t.__baz)
it throws the error shown in below example.
But prints if we do:
print(t._Test__baz)
USE it from CLASS It Self :self.__baz=42
It prevents subclass changing the attribute, its a prevention mechanism.
EXAMPLE:
========
class Test: def __init__(self): self.foo=11
self._bar=23 #It is by convention,Name is treated private by a programmer
self.__baz=42 #Called dunderBaz
t=Test() #t is the object for the class Test print(t) print(dir(t)) print(t.foo) print(t._bar) #print(t.__baz)
Output:
<__main__.Test object at 0x103a9f4e0>
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']
11
23
NOTE:
=====
When we check the attributes on the object dir(t),when we look for foo,_bar,__baz in above
list,we notice that foo and __bar appear same as as it is in class(Nothing Change),
when we notice __baz its _Test__baz (Python Interpretor Does this to prevent the subclasses, name mangling, i.e when Test class is inherited when they want to use the same name)
so
print(t.foo)
print(t._bar)
Prints proper values:
But if we do:
print(t.__baz)
it throws the error shown in below example.
But prints if we do:
print(t._Test__baz)
USE it from CLASS It Self :self.__baz=42
It prevents subclass changing the attribute, its a prevention mechanism.
class Test: def __init__(self): self.foo=11
self._bar=23
self.__baz=42 #Name Mangling
t=Test() # print(t)
# print(dir(t))
# print(t.foo)
# print(t._bar)
print(t.__baz)
Output:
Traceback (most recent call last):File "/Users/mbidsar/Desktop/Python/Python-Programs-Practise/core/Manish-Pgms/_and__.py",
line 12, in <module> print(t.__baz) AttributeError: 'Test' object has no attribute '
Taken from below Video Reference: