Trouble Accessing Python Superclass Attributes
Solution 1:
Simple. __foo
contains 2 underscores in the beginning, so it's assumed to be class-private method and it's transformed into _Classname__method
.
When you request access to the attribute named as such on Bar
object it asks Bar
class if it has this method (not Foo
class), so self.__foo
is always the same as self._Bar__foo
.
From the documentation:
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.
If you modify your code slightly
classFoo:
def__init__(self, foo):
self.__foo = foo
asserthasattr(self, '_Foo__foo'), 'Attribute has been just created'classBar(Foo):
defbar(self):
asserthasattr(self, '_Foo__foo'), 'No errors, thanks to inheritance'
assert
statements will not cause any AssertionError
s.
Add __getattribute__
method to Bar
class to capture all requests to Bar
objects:
classBar(Foo):
defbar(self):
print('Accessing __foo from bar')
print(self.__foo)
def__getattribute__(self, name):
print('Requested', name)
returnsuper().__getattribute__(name)
b = Bar('foobar')
b.bar()
There will be 3 lines (apart from AttributeError
) in the output:
Requested bar
Accessing __foo from bar
Requested _Bar__foo # AttributeError follows
As you can see, if attribute you are requesting has 2 leading underscores, Python is renaming it on the fly.
Post a Comment for "Trouble Accessing Python Superclass Attributes"