16

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

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

import yaml

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

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

4

2 回答 2

21

PyYAML 转储程序使用一种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.loadFalseTrue获取不同的输出布局。

你不能让它工作的原因是表示器匹配的结果id()和对于单独生成的两个元组来说是相同的,只要元素是相同的。


¹我只用我是作者的ruamel.yaml尝试了这个,它是 PyYAML 的增强版本,但是对于这个来说,两者应该是一样的。

于 2015-06-06T12:02:41.253 回答
2

此方法适用于 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
于 2021-03-29T11:11:46.220 回答