python __getattribute__覆盖和@property装饰器

thk*_*ang 0 python attributes class

我不得不写一些覆盖的类__getattribute__.基本上我的类是一个容器,它将每个用户添加的属性保存到self._meta字典中.

class Container(object):
    def __init__(self, **kwargs):
        super(Container, self).__setattr__('_meta', OrderedDict())
        #self._meta = OrderedDict()
        super(Container, self).__setattr__('_hasattr', lambda key : key in self._meta)

        for attr, value in kwargs.iteritems():
            self._meta[attr] = value

    def __getattribute__(self, key):
        try:
            return super(Container, self).__getattribute__(key)
        except:
            if key in self._meta : return self._meta[key]
            else:
                raise AttributeError, key

    def __setattr__(self, key, value):
        self._meta[key] = value
#usage:
>>> a = Container()
>>> a
<__main__.Container object at 0x0000000002B2DA58>
>>> a.abc = 1 #set an attribute
>>> a._meta
OrderedDict([('abc', 1)]) #attribute is in ._meta dictionary
Run Code Online (Sandbox Code Playgroud)

我有一些继承Container基类的类,他们的一些方法有@property装饰器.

class Response(Container):
    @property
    def rawtext(self):
        if self._hasattr("value") and self.value is not None:
            _raw = self.__repr__()
            _raw += "|%s" %(self.value.encode("utf-8"))

            return _raw
Run Code Online (Sandbox Code Playgroud)

问题是.rawtext无法访问.(我得到AttributeError错误.)在每一个键._meta是可访问的,由每增加属性__setattr__object基类是可访问的,但方法对性能的@property装饰是没有的.我认为这与我__getattribute__Container基类中重写的方式有关.我该怎么做才能使@property访问属性?

mgi*_*son 6

我想你应该考虑一下__getattr__而不是在__getattribute__这里.区别在于: __getattribute__如果存在则被无条件地调用 - __getattr__只有在python无法通过其他方式找到属性时才会调用它.