-
Notifications
You must be signed in to change notification settings - Fork 0
Name Manggling
| Naming | Interprepter Read |
|---|---|
python _name |
not enforce by python interpreter |
__name |
enforce by python interpreter |
__name__ |
python built in method or called magic method / dunder method |
The table above shown how naming with underscore was preceived by the interpreter. The single underscore indicate that particular naming for method or method is a private method which shouldn't be called directly.
Python didn't have any keyword to enforce certain attributes or method as private or public, but in order to define certain method or attributes as private python have special convention which is the single underscore.
The single underscore method was not enforce by the interpreter so the method with single underscore naming can still be called. The double underscore naming will be read and interpreted by the python interpreter and for the name manggling, the naming will append class name to the name to create a unique name.
Using single and double underscore as naming:
from pprint import pprint
#creating the class for test with initalization of all value using different name manggling method
class Test:
def __init__(self):
self.fname = 'fitri'
self._fname = ' muhammad fitri'
self.__fname = 'fitri rahim'
#creating class instances
instance = Test()
#printing location of the object
print(instance)
#getting all the attributes and method from the object
pprint (dir(instance))The output to the console:
['_Test__fname',
'_fname',
'fname']Notice for the double underscore what python did it attach this attributes name to the _Test which is the class for the attributes. This what called name maggling, python manggling (wrapping) the name with the class name.
The name manggling can't be used inside another class, it can only be called and use from the class it was created on. (unless we specify the underscore class etc _Test__fname)
Creating the inheritance class and accessing the variable using self.__fname will output error example:
class Inherite (Test):
def printing (self):
print (self.__fname)
new = Inherite()
new.printing()AttributeError: 'Inherite' object has no attribute '_Inherite__fname'
What are the correct way to access the private attributes / name manggling?
class Test:
def __init__(self):
self.fname = 'fitri'
self._fname = ' muhammad fitri'
self.__fname = 'fitri rahim'
def some_operation(self):
print (self._fname)
#creating class instances
instance = Test()
instance.some_operation()From the documentation:
Name mangling is helpful for letting subclasses override methods without breaking intraclass method calls. For example:
From https://docs.python.org/3/tutorial/classes.html
class Mapping:
def __init__(self, iterable):
self.items_list = []
self.__update(iterable)
def update(self, iterable):
for item in iterable:
self.items_list.append(item)
__update = update # private copy of original update() method
class MappingSubclass(Mapping):
def update(self, keys, values):
# provides new signature for update()
# but does not break __init__()
for item in zip(keys, values):
self.items_list.append(item)From the stackoverflow:
All previous answers are correct but here is another reason with an example. Name Mangling is needed in python because to avoid problems that could be caused by overriding attributes. In other words, in order to override, the Python interpreter has to be able to build distinct id for child method versus parent method and using __ (double underscore) enable python to do this. In below example, without __help this code would not work.
From https://stackoverflow.com/questions/1162234/what-is-the-benefit-of-private-name-mangling-in-python
class Parent:
def __init__(self):
self.__help()
def help(self):
print("Parents run first")
__help = help # private copy of original help() method
class Child(Parent):
def help(self):
print ("child run second")print ("list parent & child responsibilities") c = Child() c.help()
Once the green highlighted code, the method will be updated.
*** this is to avoid the method accidently override the help() method on the Parent class which suppose to run on itialization.
In simple word, this name maggling is to avoid collision of the same method name.
Using inheritance, the parent class will run first, during this run, the __help will maggling into _Parent__help which then assign to method help() in the Parent class.
Then in the child class, again, the __help name will maggling into _Child__help which then assigned to help() method inside the Child class.
So in simple word, during inheritance of Parent class to child Class this happen:
1. _Parent__help = help () # inside of Parent class, which print "Parents run first"
2. Then it initiate the child class which using same method name help() when it was called in the code highlighted in green above.
Both using same method name help() but using name maggling, the Parent help() method can be run safely without overriden by the Child class help() method.
Comparing no name maggling and with name maggling (self example):
Without name maggling:
from pprint import pprint
class BaseMethod: def init (self): self.printing()
def printing (self):
print ("I want this to print first before subclass")
class SubMethod (BaseMethod): def printing (self): print ("This one is second")
child = SubMethod() child.printing()
Print output: This one is second This one is second
** the printing method got update with the child.
With name maggling
from pprint import pprint
class BaseMethod: def init (self): self.__printing()
def printing (self):
print ("I want this to print first before subclass")
__printing = printing
class SubMethod (BaseMethod): def printing (self): print ("This one is second")
child = SubMethod() child.printing()
Print output: I want this to print first before subclass This one is second
** the printing method stay the same becasue the __printing save the method.
After some study:
The name mangling is to avoid the original method overriden by new method that share the same name, the __name will store the method inside a name manggling so it can be accesed without being overriden when same name method used.
Simple word, name maggling with double underscore on the beginning of the name, only intended to use as private method or only inside of its own class!
https://docs.python.org
https://knpcode.com
https://stackoverflow.com