I thought they were the same before I ran this code:
class B(object):
def show(self):
self.__a = "test"
print "B"
def this_b(self):
print "this_b"
print self.__a
print getattr(self, '__a') #exception
class C(B):
def show(self):
print "C"
# B.show(self)
super(C, self).show()
def call(self):
print "call"
self.show()
self.this_b()
# print self.__a
C().call()
It raises AttributeError: 'C' object has no attribute '__a'
with the getattr
statement, but why?
It is because of the Private name mangling.
Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier
__spam
occurring in a class namedHam
will be transformed to_Ham__spam
. This transformation is independent of the syntactical context in which the identifier is used. If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen. If the class name consists only of underscores, no transformation is done.
When you do
self.__a
Private name mangling will be taken care automatically. But when you do
print getattr(self, '__a')
you have to do it manually, like this
print getattr(self, '_B__a')
# test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With