Python PyYAML解析为任意对象
我有以下Python 2.6程序和YAML定义(使用):Python PyYAML解析为任意对象,python,yaml,pyyaml,Python,Yaml,Pyyaml,我有以下Python 2.6程序和YAML定义(使用): 这将导致以下输出: {'product':{'sku':123',name':'product X','features':[{'weight':'10kg','size':'10x30cm'}]} 可以使用x? 我想提出以下几点: print x.features[0].size 我知道可以从现有类创建和实例,但这不是我在这个特定场景中想要的 编辑: 更新了关于“强类型对象”的混淆部分 根据Alex Martelli的建议,将对
这将导致以下输出:
{'product':{'sku':123',name':'product X','features':[{'weight':'10kg','size':'10x30cm'}]}
可以使用x
?
我想提出以下几点:
print x.features[0].size
我知道可以从现有类创建和实例,但这不是我在这个特定场景中想要的
编辑:
- 更新了关于“强类型对象”的混淆部分
- 根据Alex Martelli的建议,将对
功能的访问权限更改为索引器
.features(0)
比.features[0]
(这是一种索引列表的更自然的方式!),但是,当然,这是可行的。例如,一个简单的方法可能是:
def wrap(datum):
# don't wrap strings
if isinstance(datum, basestring):
return datum
# don't wrap numbers, either
try: return datum + 0
except TypeError: pass
return Fourie(datum)
class Fourie(object):
def __init__(self, data):
self._data = data
def __getattr__(self, n):
return wrap(self._data[n])
def __call__(self, n):
return wrap(self._data[n])
所以x=wrap(x['product'])
应该满足您的愿望(为什么您要跳过该级别,而您的总体逻辑显然需要x.product.features(0).size
,我不知道,但很明显,跳过最好在调用时应用,而不是在包装器类或我刚才展示的包装器工厂函数中硬编码)
编辑:正如OP所说,他确实想要功能[0]
而不是功能(0)
,只需将最后两行更改为
def __getitem__(self, n):
return wrap(self._data[n])
i、 例如,定义\uuuuu getitem\uuuuuuuuuuu
(作为索引基础的神奇方法),而不是\uuuuuuuuuuuuuuuuu调用(作为实例调用基础的神奇方法)
“一个现有类”(这里是,Fourie
)的替代方案是在反思包装好的dict的基础上动态创建一个新类——也是可行的,但严重的是深灰色,即使不是黑色,也是神奇的,并且没有我能想到的任何真正的操作优势
如果OP能够确切地解释为什么他可能渴望在运行中创建类的元编程高峰,他认为他可能会获得什么样的优势,等等,我将展示如何做到这一点(并且,可能,我还将展示为什么对优势的渴望会而不是事实上会存在;-)。但是简单性在任何编程工作中都是一个重要的品质,当像上面这样简单、直截了当的代码工作得很好时,使用“深度黑暗魔法”通常不是最好的主意!) @Alex,谢谢你的回答。很抱歉,我把功能的索引器弄糟了,你是对的,它应该是.features[0]
。我正在更新我的帖子,以避免进一步的混乱。只需覆盖\uuu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuu
而不是\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。作为Python的新手,我不知道神奇的方法,这是一个多么伟大的概念啊!希望我能在以后的某个场合,在创建动态类时,启发你的想法。我的问题的绝妙解决方案。
def __getitem__(self, n):
return wrap(self._data[n])