'super'对象未调用__getattr__ [英] 'super' object not calling __getattr__

查看:96
本文介绍了'super'对象未调用__getattr__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将一个对象包裹在另一个对象中. 包装器"通过覆盖__getattr__来访问包装的"对象中的属性. 直到我需要重写子类上的属性,然后使用super()从基类访问该属性为止,该方法才能很好地工作.

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().

我仍然可以直接从__getattr__访问属性,但是为什么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不允许隐式调用诸如__getattr__之类的"hook"函数.我不确定为什么要用这种方式实现(这可能是一个很好的理由,而且由于超级对象具有自定义的__getattribute____get__方法,所以事情已经很混乱了),但似乎只是这样事情是这样.

According to this, super does not allow implicit calls of "hook" functions such as __getattr__. I'm not sure why it is implemented this way (there's probably a good reason and things are already confusing enough since the super object has custom __getattribute__ and __get__ methods as it is), but it seems like it's just the way things are.

这篇文章似乎可以使您的工作变得简单一些.似乎问题在于,当隐式调用函数时,由__getattribute__引起的额外的间接层将被忽略.做foo.x等同于

This post appears to clear things up a little. It looks like the problem is the extra layer of indirection caused by __getattribute__ is ignored when calling functions implicitly. Doing foo.x is equivalent to

foo.__getattr__(x)

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

(Assuming no __getattribute__ method is defined and x is not in foo.__dict__) However, it is NOT equivalent to

foo.__getattribute__('__getattr__')(x)

由于super返回了代理对象,因此它具有一个间接层,这会导致事务失败.

Since super returns a proxy object, it has an extra layer of indirection which causes things to fail.

P.S.完全不需要__getattr__功能中的self.__dict__检查.仅当字典中不存在该属性时才调用__getattr__. (如果要始终调用__getattribute__,请使用__getattribute__,但是您必须非常小心,因为即使if name in self.__dict__之类的简单内容也会引起无限递归.

P.S. The self.__dict__ check in your __getattr__ function is completely unnecessary. __getattr__ is only called if the attribute doesn't already exist in your dict. (Use __getattribute__ if you want it to always be called, but then you have to be very careful, because even something simple like if name in self.__dict__ will cause infinite recursion.

这篇关于'super'对象未调用__getattr__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆