避免在PyYAML中引用

时间:2012-11-22 19:14:12

标签: python yaml

我将YAML与PyYAML一起使用。在转储嵌套结构后,有没有办法避免* id002引用?为了便于阅读,我想在那里看到实际的(元组)值。

在尝试制作一个迷你示例时,我注意到只有当我使用相同的id对象时才会发生:

import yaml

t = ("b", "c")
x = {(1, t):1, (2, t):2, }
print(yaml.dump(x))

所以我认为copy.copy()可以解决这个问题,但是对于元组它似乎不起作用:(我可以创建一个具有不同id的新元组吗?

2 个答案:

答案 0 :(得分:11)

PyYAML转储器使用ignore_aliases方法来防止基本类型以这种方式“锚定”和“引用”。您可以将该方法重写为始终ignore_aliases,而不依赖于传入的任何对象。默认情况下,yaml.Loader类中使用yaml.load类:

t = ("b", "c")
x = {(1, t):1, (2, t):2, }

yaml.Dumper.ignore_aliases = lambda *args : True

yaml.dump(x, sys.stdout)

会得到你:

? !!python/tuple
- 1
- !!python/tuple [b, c]
: 1
? !!python/tuple
- 2
- !!python/tuple [b, c]
: 2

这样你就不必尽力了,并使用相同的哈希来获得看起来不同的元组。您可能希望在default_flow_style上向yaml.loadFalse提供True参数,以获得不同的输出布局。

你无法使其工作的原因是,表示者匹配id()的结果,只要元素相同,两个元组的结果是相同的。

¹我只用ruamel.yaml尝试了这个,其中我是作者,它是PyYAML的增强版本,但为此,两者都应该相同。

答案 1 :(得分:1)

This method 在 Python 2 和 Python 3 上对我有用,并且不需要猴子补丁:

import yaml

class NoAliasDumper(yaml.SafeDumper):
    def ignore_aliases(self, data):
        return True

t = ("b", "c")
x = {(1, t):1, (2, t):2, }
print(yaml.dump(x, Dumper=NoAliasDumper))

产生的结果

? - 1
  - [b, c]
: 1
? - 2
  - [b, c]
: 2