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