Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between getattr(self, '__a') and self.__a in python?

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?

like image 307
LeoShi Avatar asked Apr 26 '14 02:04

LeoShi


1 Answers

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 named Ham 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
like image 190
thefourtheye Avatar answered Oct 14 '22 00:10

thefourtheye