python _ugetAttribute _uu重写和@property decorator

python _ugetAttribute _uu重写和@property decorator,python,class,attributes,Python,Class,Attributes,我必须编写某种类型的类来重写\uuu getattribute\uuu。 基本上,我的类是一个容器,它将每个用户添加的属性保存到self.\u meta这是一个字典 class Container(object): def __init__(self, **kwargs): super(Container, self).__setattr__('_meta', OrderedDict()) #self._meta = OrderedDict()

我必须编写某种类型的类来重写
\uuu getattribute\uuu
。 基本上,我的类是一个容器,它将每个用户添加的属性保存到
self.\u 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

问题是,
.rawtext
无法访问。(我得到attributeerror。)
\uMeta
中的每个键都是可访问的,由
对象的
\uuuSetAttr\uuuUn/code>添加的每个属性都是可访问的,但@property decorator的属性方法是不可访问的。我认为这与我在
Container
基类中重写
\uuu getattribute\uuu
的方式有关。我应该怎么做才能使
@property
中的属性可访问?

我认为您可能应该考虑查看而不是查看这里。区别在于:
\uuuuu getattribute\uuuu
在存在的情况下被传统调用--
\uuuu getattr\uuuu
仅在python无法通过其他方式找到属性的情况下被调用。

我完全同意mgilson的观点。如果您想要一个示例代码,该代码应该与您的代码等效,但可以很好地处理属性,您可以尝试:

class Container(object):
    def __init__(self, **kwargs):
        self._meta = OrderedDict()
        #self._hasattr = lambda key: key in self._meta  #???
        for attr, value in kwargs.iteritems():
            self._meta[attr] = value

    def __getattr__(self, key):
        try:
            return self._meta[key]
        except KeyError:
            raise AttributeError(key)

    def __setattr__(self, key, value):
        if key in ('_meta', '_hasattr'):
            super(Container, self).__setattr__(key, value)
        else:
            self._meta[key] = value
我真的不明白你的
\u hasattr
属性。你把它作为一个属性,但它实际上是一个可以访问
self
的函数。。。这不是一种方法吗? 实际上,我认为您应该简单地使用内置函数hasattr

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

            return _raw
请注意,
hasattr(container,attr)
也将为
\u meta
返回
True

另一件让我困惑的事情是,为什么要使用
OrderedDict
。我的意思是,你迭代了
kwargs
,迭代的顺序是随机的,因为它是一个普通的
dict
,然后在
OrderedDict
中添加项目。现在您有了
\u meta
,其中包含随机顺序的值。 如果您不确定是否需要特定的订单,只需使用
dict
,然后最终切换到
orderedict

顺便说一句:永远不要使用
try:。。。除外:
但不指定要捕获的异常。在代码中,您实际上只想捕获
AttributeError
s,因此您应该执行以下操作:

try:
    return super(Container, self).__getattribute__(key)
except AttributeError:
    #stuff

你真的需要使用
\uuuuuuGetAttribute\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,因此,我不应该触摸
\uuuuu getattribute\uuuu
而只修改
\uuuu getattr\uuuu
来让python协议完成这项工作?@thkang——这就是我的建议,是的:)。按照您的
\uuuu setattr\uuuuu
的方式,我认为它应该做正确的事情。(也就是说,它应该将属性打包到元有序dict中,但仍然允许在子类上使用属性和方法!)感谢您的努力。我明白你对夸尔斯的看法——我遗漏了一些关键的东西。不需要kwargs,正如您所说:DQ问题-在这里如何实现delete方法?
try:
    return super(Container, self).__getattribute__(key)
except AttributeError:
    #stuff