gpt4 book ai didi

python - “ super ”对象不调用 __getattr__

转载 作者:IT老高 更新时间:2023-10-28 21:13:50 26 4
gpt4 key购买 nike

我将一个对象包裹在另一个对象中。“Wrapper”通过覆盖 __getattr__ 来访问“Wrapped”对象的属性。这很好用,直到我需要覆盖子类的属性,然后使用 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()

最佳答案

According to this, super 不允许隐式调用诸如 __getattr__ 之类的“钩子(Hook)”函数。我不确定为什么要以这种方式实现(可能有一个很好的理由,而且事情已经很困惑了,因为 super 对象具有自定义的 __getattribute____get__ 方法),但似乎事情就是这样。

编辑:This post appears to clear things up a little.看起来问题是在隐式调用函数时忽略了由 __getattribute__ 引起的额外间接层。做 foo.x 相当于

foo.__getattr__(x)

(假设没有定义 __getattribute__ 方法并且 x 不在 foo.__dict__ 中)但是,它不等同于

foo.__getattribute__('__getattr__')(x)

由于 super 返回一个代理对象,它有一个额外的间接层导致事情失败。

附: self.__dict__ 检查你的 __getattr__ 函数是完全没有必要的。 __getattr__ 仅在您的字典中不存在该属性时才被调用。 (使用 __getattribute__ 如果你希望它总是被调用,但是你必须非常小心,因为即使像 if name in self.__dict__ 这样简单的东西也会导致无限递归.

关于python - “ super ”对象不调用 __getattr__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12047847/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com