我有一个物体包裹在另一个物体内."Wrapper"通过覆盖从"Wrapped"对象访问属性__getattr__.这很有效,直到我需要覆盖子类的属性,然后使用基类访问该属性super().
我仍然可以直接访问该属性,__getattr__但为什么不起作用super()?
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()
Run Code Online (Sandbox Code Playgroud)
Ant*_*ony 12
据此, super不允许隐式调用"钩子"函数,如__getattr__.我不确定为什么它以这种方式实现(可能有一个很好的理由,因为超级对象具有自定义__getattribute__和__get__方法,所以事情已经足够令人困惑),但看起来它只是事物的方式.
编辑:这篇文章似乎清楚了一点.看起来问题是在__getattribute__隐式调用函数时忽略了引起的额外的间接层.做foo.x就等于
foo.__getattr__(x)
Run Code Online (Sandbox Code Playgroud)
(假设没有__getattribute__定义方法且x不在foo.__dict__)但是,它不等同于
foo.__getattribute__('__getattr__')(x)
Run Code Online (Sandbox Code Playgroud)
由于super返回一个代理对象,它有一个额外的间接层,导致事情失败.
PS self.__dict__检查您的__getattr__功能是完全没必要的.__getattr__只有在你的dict中不存在该属性时才会调用它.(__getattribute__如果你想要它总是被调用,请使用,但是你必须非常小心,因为即使是简单的东西if name in self.__dict__也会导致无限递归.
| 归档时间: |
|
| 查看次数: |
7866 次 |
| 最近记录: |