一点背景:你会注意到我的评论描述了我以后要经历的事情。假设我有以下对象。。。在
#!/usr/bin/python
import os
import sys
class ContainerField(object):
''' An attribute/object storage device '''
def __init__(self, field=None, value=None):
self.m_field = field
self.m_value = value
def __getattr__(self, key):
'''
What can we do here that runs the .get() command but -only- if the key
does not exist.
'''
# super(ContainerField, self).__getattr__(key)
def __call__(self):
return self.get()
def value(self):
return self.m_value
def setValue(self, value):
self.m_value = value
def _recurseSetAttr(self, attr, values):
'''Generate our attributes/objects and store them succinctly.'''
# Container
# \_Container
# \_Container
# \_Container...
for field, value in values.items():
if not hasattr(attr, field):
setattr(attr,
field,
# field type is known from model caching
ContainerField(value=value, field=field_type(field)))
fdbf = getattr(attr, field)
if isinstance(value, dict):
self._recurseSetAttr(fdbf, value)
else:
fdbf.setValue(value)
def get(self):
# Create the new object from scratch and proliferate it's
# attributes recursively. 'values' come in the form of a
# dictionary that we can then use to setattr().
# So... Create container, set value, find keys for this
# and create containers that hold the values of those keys
# and repeate...
self._recurseSetAttr(self, attr, values)
现在,当生成对象时,我可以有一个dict,它看起来像这样:{"myContainer" : { "id" : 2, "foo" : { "id" : 3, "bar" : 1 } }}
,一旦创建,可以这样调用:myContainer.foo.id.value()
在这个场景中有一个self.m_field
,它告诉应用程序对象的实际数据类型。这引用了Django模型,但任何python都可以应用。在
作为实例化的一部分,所有容器都有一个id
(或pk
)键。这是强制性的。在
理想情况下,我们填充顶层属性,只有当用户请求其下的属性时,我们才会根据id
值和field
类型构造它们。在
最后,假设myContainer.foo.bar
属性具有外键字段类型。如果我们调用myContainer.foo.bar.newkey.value()
,应用程序应该知道“newkey”属性不存在,查询我们的django实例,将bar
属性存储为现在更填充的容器,并返回已放入内存的newkey
值。在
我希望它是一个简单的hasattr()
,但是Python似乎只是将getattr()
与默认的None
一起使用(递归是真实的!)。我也有很多麻烦让一个try: except:
工作。在
当我写这篇文章时,我意识到由于依赖于getattr()
和hasattr()
的递归属性设置,它可能会变得更加复杂,任何建议都将不胜感激。-干杯
看看这个:
这里,不是返回
'created a new key...'
,而是创建一个新属性并返回它。在您可以考虑将@property decorator用于私有内部字段。这个想法应该是:
所以要回答问题的第一部分:如何在属性尚未定义的情况下,}。python类中有两种属性访问方法:}。第一个在每次尝试属性查找时调用,第二个仅在常规属性查找系统失败(包括超类中的查找)时调用。因为您定义的是
__getattr__
调用{__getattribute__
和{__getattr__
,它只在属性不存在时调用,所以您可以简单地将其代理为对.get
的调用。如果您试图查找self
的另一个属性,self
的另一个属性,__getattr__
内部也不存在该属性。避免这种情况的方法是有一个需要特殊处理的键列表,并检查当前请求的属性是否是其中之一。这通常只在实现__getattribute__
时需要。在请注意,}未定义。如果我知道}需要什么值,我会给出一个更具体的答案。在
.get
方法有一个问题:attr
和{.get
的attr
和{相关问题 更多 >
编程相关推荐