'Python name mangling allows access both ways
So I have come across a very interesting behavior of python name mangling. Consider the following code
class C:
def __init__(self):
self.__c = 1
@staticmethod
def change(instance):
print(dir(instance))
print(instance.__c)
print(instance._C__c)
Here I create a private field __c and expect to have direct access to it from within class and access via _C__c from outside of the class. So, if we pass an instance of C to C.change either 2nd or 3rd print should fail.
Lets check:
>>> c = C()
>>> dir(c)
['_C__c', '__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__', 'change']
>>> C.change(c)
['_C__c', '__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__', 'change']
1
1
First, for debug we print all available members of c with dir(c). Then we call C.change passing it the variable c.
Hmm, that is unexpected, no errors.
So, first print in change shows us all the available entries of the instance object. Here we see that field __c is available as _C__c. That seems ok, since we access not through self, but through another variable.
Having such output from 'dir' I expect print(instance.__c) to fail with AttributeError.
However, unexpectedly, it works just fine!
This really confuses me, since I do not understand, why is __c accessible and if it is so by design, then why is it not listed in dir output?
Solution 1:[1]
__-prefixed names work fine as-is inside the class's own methods. It's only outside the class (including in its subclasses) that the modified name is needed to access the attribute, due to name-mangling.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | chepner |
