PyYAML解析为任意对象

2024-04-23 14:11:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下python2.6程序和YAML定义(使用PyYAML):

import yaml

x = yaml.load(
    """
        product:
           name     : 'Product X'
           sku      : 123
           features :
             - size    :  '10x30cm'
               weight  :  '10kg'

         """
    )

print type(x)
print x


结果如下:
<type 'dict'>
{'product': {'sku': 123, 'name': 'Product X', 'features': [{'weight': '10kg', 'size': '10x30cm'}]}}

是否可以使用x中的字段创建对象?

我想说的是:

^{pr2}$

我知道可以从现有的类中创建和实例,但这不是我在这个特定场景中想要的。在

编辑:

  • 更新了关于“强类型对象”的令人困惑的部分。在
  • 按照Alex Martelli的建议,将对features的访问权更改为索引器

Tags: nameimport程序yamlsize定义typeproduct
1条回答
网友
1楼 · 发布于 2024-04-23 14:11:08

所以你有一个字典,它有字符串键和值,可以是数字,嵌套字典,列表,你想把它包装成一个实例,让你用属性访问代替dict索引,用“call with an index”代替list indexing不确定“强类型”与此有什么关系,或者为什么您认为.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,我不知道,但是很明显,跳过更好地应用于调用点,而不是硬编码在包装器类或我刚刚展示的包装工厂函数中)。在

编辑:正如操作人员所说,他确实想要features[0],而不是{},只需将最后两行更改为

^{pr2}$

也就是说,定义__getitem__(索引底层的魔术方法),而不是__call__(实例调用的底层魔术方法)。在

“现有类”(这里,Fourie)的另一种选择是基于对包装的dict进行反思的基础上动态创建一个新的类,这也是可行的,但是严重的深灰色,如果不是真的黑色的,魔法,而且没有任何我能想到的实际操作优势。在

如果OP能够明确说明为什么他会渴望动态创建类的元编程高峰,他认为他可能会从中获得什么好处,等等,那么我将展示如何做到这一点(而且,也许,我还将展示为什么渴望优势的人实际上会不在那里;-)。但是在任何编程工作中,简单性都是一个重要的品质,当上面这样简单、直接的代码运行得很好时,使用“深暗魔法”通常不是最好的主意!-)在

相关问题 更多 >