January 19, 2022
Python Underscores Part 2
We are going to continue exploring the uses of the underscores.
Trailing underscores
var_
Well, trailing underscores are used only for giving Python's keyword names to variables.
print_ #instead of print while_ #instead of while
Double leading (dunders) underscores
__var
Avoid naming conflicts in subclasses by rewriting the name of a class attribute in a class context — name mangling. The attribute would be protected from being overridden.
class Parent: def __init__(self): self.foo = 11 self.__baz = 23 t = Parent() print(dir(t))
['_Parent__baz', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo']
class Child(Parent): def __init__(self): super().__init__() self.foo = 'overridden' self.__baz = 'overridden' t2 = Child() t2.foo # overriden t2.__baz # AttributeError: #"'Child' object has no attribute '__baz'"
Let's continue exploring the chunk of code from the example:
print(dir(t2)) #a long list of attributes t2._Child__baz # ovverriden t2._Parent__baz # result is 42
We have noticed the variables that are reserved by using dir().
The name mangling is transparent to a programmer. That my seem confusing, right?
class ManglingTest: def __init__(self): self.__mangled = 'hello' def get_mangled(self): return self.__mangled ManglingTest().get_mangled() # 'hello' ManglingTest().__mangled # AttributeError: #"'ManglingTest' object has no attribute '__mangled'"
We are getting access via the class method that uses the original name.
Spend a little time and play with the example to get it more clearly. I know that you can get it.