如何将Perl的blessed对象转为Python可读的YAML
我们有一个用Perl Dancer写的REST网络服务。它以YAML格式返回Perl数据结构,同时也接受YAML格式的参数——这个服务是为了和其他团队合作,他们用Python来查询这个服务。
问题是——如果我只是通过Dancer的序列化返回一个普通的Perl哈希,一切都能正常工作。无论是JSON、YAML还是XML,都能顺利完成任务。
但是,有时候我们需要返回Perl对象,这样Python可以把这些对象作为参数再传回去,以帮助减少不必要的加载等。我尝试了一下,发现YAML是唯一能在Dancer中处理Perl的“受保护”对象的格式。
问题在于,Python的YAML无法解析Perl对象的YAML(而对于普通的Perl哈希的YAML,它却没有问题)。
Perl对象在YAML中的表现是这样的:
第一个:
--- &1 !!perl/hash:Sequencing_API
第二个:
--- !!perl/hash:SDB::DBIO
它报错信息是这样的:
yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:perl/hash:SDB::DBIO'
而普通的文件似乎是这样传递的:
---
fields:
library:
看起来在---
后面的额外内容导致了问题。我该怎么解决这个问题?还是说我试图通过传递Perl对象做得太多了?
1 个回答
简单来说,
!!
是 YAML 的一种简写方式,代表 tag:yaml.org,2002:
... 所以 !!perl/hash
实际上就是 tag:yaml.org,2002:perl/hash
。
接下来,你需要告诉 Python 的 YAML 库该如何处理这种类型。
所以你可以为它添加一个构造函数,像这样:
import yaml
def construct_perl_object(loader, node):
print "S:",suffix,"N:",node
return loader.construct_yaml_node(node)#this is likely wrong ....
yaml.add_multi_constructor(u"tag:yaml.org,2002:perl/hash:SDB::DBIO", construct_perl_object)
yaml.load(yaml_string)
或者你也可以直接解析出来,或者返回 None 也行……仅凭这一行很难测试……但这可能就是你想要的。