【问题标题】:Avoid references in PyYAML避免在 PyYAML 中引用
【发布时间】:2012-11-11 05:06:25
【问题描述】:

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

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

import yaml

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

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

【问题讨论】:

  • 也许您可以显示代码以便我们重新制作
  • 它是否适用于x = {(1, t):1, (2, tuple(t)):2}
  • No :( 不知何故a=(1,); a is tuple(a) 也预测没有新的元组。
  • 啊,但是tuple(list(t)) 有效:)

标签: python yaml


【解决方案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

【讨论】:

  • 您提供的链接中的答案 (ttl255.com/yaml-anchors-and-aliases-and-how-to-disable-them) 对我有用。对其他人来说,当您覆盖 yaml.SafeDumper() 类时,您必须使用 yaml.dump() 而不是 yaml.safe_dump() 来摆脱 YAML 引用。使用 yaml.safe_dump() 将导致此错误:“TypeError: dump_all() got multiple values for keyword argument 'Dumper'
【解决方案2】:

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

这样您就不必尽最大努力让具有相同哈希的元组看起来不同。您可能希望将 yaml.load 上的 default_flow_style 参数提供给 FalseTrue 以获得不同的输出布局。

您无法使其工作的原因是表示器与 id() 的结果匹配,并且只要元素相同,两个元组的结果都是相同的。


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

【讨论】:

  • 另外,如果您使用 yaml.safe_dump() 从 yaml 中删除 ? !!python/tuple。您将需要覆盖yaml.SafeDumper.ignore_aliases。然后示例变为:yaml.SafeDumper.ignore_aliases = lambda *args : Trueyaml.safe_dump(x, sys.stdout)
  • FWIW 现在可以正常工作了(PyYAML 5.3.1)。在一些较新版本的 PyYAML 设置中,这会导致异常,至少在我的代码中是这样。
  • 谢谢!烦人的是 2021 年了,最新的 PyYAML 版本仍然需要这个技巧才能正常工作。
  • @RafaelAlves,您的回答不适用于我主机上的 yaml.safe_dump() 调用。 PyYAML 是否必须是特定版本才能使您的代码正常工作?
猜你喜欢
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 2011-01-27
  • 2012-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多