I have one object wrapped inside another.
The "Wrapper" accesses the attributes from the "Wrapped" object by overriding __getattr__
.
This works well until I need to override an atribute on a sub class, and then access the attribute from the base class using super()
.
I can still access the attribute directly from __getattr__
but why does super()
not work?
class Wrapped(object):
def __init__(self, value):
self.value = value
def hello_world(self):
print 'hello world', self.value
class Wrapper(object):
def __init__(self, obj):
self.wrapped_obj = obj
def __getattr__(self, name):
if name in self.__dict__:
return getattr(self, name)
else:
return getattr(self.wrapped_obj, name)
class Subclass(Wrapper):
def __init__(self, obj):
super(Subclass, self).__init__(obj)
def hello_world(self):
# this works
func = super(Subclass, self).__getattr__('hello_world')()
# this doesn't
super(Subclass, self).hello_world()
a = Wrapped(2)
b = Subclass(a)
b.hello_world()
super()
is implemented as part of the binding process for explicit dotted attribute lookups such assuper().__getitem__(name)
. It does so by implementing its own__getattribute__()
method for searching classes in a predictable order that supports cooperative multiple inheritance. Accordingly,super()
is undefined for implicit lookups using statements or operators such assuper()[name]
. – Spikelet__getattr__
's code insideif name in self.__dict__:
will never be reached:__getattr__
is not called if a name is defined in the instance's__dict__
. This is a potential source of hard to find bugs. – Mcdade