如何处理自定义 PyYAML 构造函数中的递归?

2024-01-01

PyYAML 可以处理常规 python 对象中的循环图。例如:

片段#1。

class Node: pass
a = Node()
b = Node()
a.child = b
b.child = a
# We now have the cycle a->b->a
serialized_object  = yaml.dump(a)
object = yaml.load(serialized_object)

这段代码成功了,所以显然有一些机制可以防止加载序列化对象时的无限递归。当我编写自己的 YAML 构造函数时,如何利用它?

例如,说Node是一个具有瞬态字段的类foo and bar和非瞬态场child. Only child应该将其放入 yaml 文档中。我希望这样做:

片段#2。

def representer(dumper, node):
  return dumper.represent_mapping("!node", {"child": node.child})

def constructor(loader, data):
  result = Node()
  mapping = loader.construct_mapping(data)
  result.child = mapping["child"]
  return result

yaml.add_representer(Node, representer)
yaml.add_constructor("!node", constructor)

# Retry object cycle a->b->a from earlier code snippet
serialized_object  = yaml.dump(a)
print serialized_object
object = yaml.load(serialized_object)

但它失败了:

&id001 !node
child: !node
  child: *id001

yaml.constructor.ConstructorError: found unconstructable recursive node:
  in "<string>", line 1, column 1:
    &id001 !node

我明白为什么了。我的构造函数不是为递归而构建的。它需要在完成构造父对象之前返回子对象,并且当子对象和父对象是同一个对象时,该操作会失败。

但显然 PyYAML 具有解决此问题的图形遍历,因为 Snippet #1 有效。也许有一个过程可以构造所有对象,第二个过程可以填充它们的字段。我的问题是,我的自定义构造函数如何与这些机制结合起来?

这个问题的答案将是理想的。但如果答案是我不能使用自定义构造函数来做到这一点,并且有一个不太理想的替代方案(例如混合YAMLObject类进入我的Node类),那么这个答案也将受到赞赏。


对于复杂类型,可能涉及递归(映射/字典、序列/列表、对象),构造函数无法一次性创建对象。因此你应该yield中构造的对象constructor()函数,然后更新此后的任何值:

def constructor(loader, data):
    result = Node()
    yield result
    mapping = loader.construct_mapping(data)
    result.child = mapping["child"]

这样就消除了错误。

¹ I don't think this is documented anywhere, without me looking at py/constructor.py intensively, while upgrading PyYAML to ruamel.yaml https://pypi.python.org/pypi/ruamel.yaml, I would not have known how to do this. A typical case of: read the source Luke

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何处理自定义 PyYAML 构造函数中的递归? 的相关文章

随机推荐

  • 弹出子导航视图时透明TabBar iOS 15

    我有一个带有 TabBar 的 SwiftUI 应用程序 如果我从 NavigationView 打开详细信息子视图 然后单击 后退 TabBar 将变为透明 显示 TabBar 图标下方的 Feed 中的项目 从主屏幕中 打开子导航详细信
  • CR 错误 无法打印组部分,因为其条件字段不存在或无效

    我继承了 CR 报告 运行时出现错误 无法打印组部分 因为其条件字段不存在或无效 格式化该部分以选择另一个条件字段 有没有办法让我知道它指的是哪个领域 关于我什么时候应该开始寻找问题的任何指示 我已经验证了 DB 它指向正确并且 Sp 返回
  • Maven 坚持认为 JAVA_HOME 未正确定义,除非我将其作为 sudo 运行

    Ubuntu 22 04 1 从 20 04 5 最新更新 当我尝试用 Maven 构建任何东西时 它会抱怨 mvn v The JAVA HOME environment variable is not defined correctly
  • Visual Studio“转到定义”菜单选项行为 - 为什么 C# 和 VB 项目之间不一致

    当使用 C 项目在 VS2005 中进行开发时 我右键单击框架方法 属性 类型并选择 转到定义 默认情况下 我们会得到一个新的锁定选项卡 其中包含从框架生成的代码 并适当标记为 来自元数据 然而 当我们在 VB NET 项目中执行相同操作时
  • 在正则表达式中匹配两个单词及其之间的一些字符

    我想在没有时对字符串进行匹配abc后面跟着一些字符 可能没有 并以 com 我尝试了以下方法 abc com or abc com or
  • 如何在 useminPrepare 中为 html 文件中的每个块定义单独的流程?

    我们在 index html 中定义了 2 个块 一个用于第三方库 另一个用于我们的应用程序文件 由于第 3 方库已经缩小 我们只想将它们连接起来 而不是丑化 我怎样才能做到这一点useminPrepare
  • 计算 ggplot2 stat_binhex 中 bin 的百分比

    我正在生成不同组的数据点的 binhex 图 每个组可能有不同的总点数 因此我希望它不是每个 bin 值的绝对点数 而是该组内总点数的百分比 这是我目前正在尝试的 d lt data frame grp c rep a 10000 rep
  • 全局安装 npm

    是否可以全局安装 npm 这是一个好主意吗 我使用 npm install 命令安装了 npm 并能够运行 npm start 然后 将我的项目发布到 github 后 我想确保如果有人克隆它 它也能运行 所以我将它克隆到我机器上的另一个目
  • .Net KeyEventArgs 返回与输入

    在 c net 应用程序中使用以下代码 字符串键 e KeyCode ToString 在 net 1 1中键 输入 在 net 3 5中键 返回 我的问题是它们为什么不同 The Keys枚举具有相同的值Enter and Return
  • Rails 每当 gem:每月 20 日

    我在互联网上搜索了这一点 并且文档并没有真正具体讨论每月的工作 所以我希望这里有人能告诉我如何做到这一点 我已经安装了whenever gem 我需要知道的是正确的语法 every month on gt 20th at gt 02 00
  • 在文件中写入大量数据的最快方法

    我正在尝试创建随机实数 整数 字母数字 字母字符串 然后写入文件直到文件大小达到10MB 代码如下 import string import random import time import sys class Generator def
  • 何时使用 Xcode 分布式构建功能

    我在一个小型 iPhone 开发团队工作 在我们的办公室里 我们在任何时候至少有 4 个 XCode 副本在网络上运行 考虑让每个人都运行它 我们使用标准 WIFI 交换机联网 因此网络速度和延迟不如有线网络 只是想知道 使用分布式构建是否
  • STL容器如何折叠?

    我需要 Haskell 的类似物foldl功能可折叠任何 STL 容器 预期签名如下 template Iterator FoldingFunction Result Result foldl Iterator begin Iterator
  • Angular/SignalR 错误:无法完成与服务器的协商

    对我的服务器使用 SignalR 对我的客户端使用 Angular 当我运行客户端时 我收到以下错误 zone js 2969 OPTIONS https localhost 27967 chat negotiate 0 Utils js
  • 如何捕获每个 PID 的网络数据包?

    有人知道一种简单的方法来要求Linux 显示来自 来自google chrome的每个互联网数据包 或 显示来自 来自PID 10275的telnet进程的每个互联网数据包 吗 telnet 示例不太有用 因为我只能使用wireshark
  • React-native ios Podfile 问题与“use_native_modules!”

    在我的反应本机项目中 电子邮件受保护 cdn cgi l email protection 在我运行的 ios 目录中pod install并得到这个错误 Invalid Podfile file no implicit conversio
  • 允许使用应用程序内主页按钮导航至主页吗?

    我想知道应用程序内主页按钮的实现 该按钮可以将您从任何页面返回到主页 据我记得 WP7 开发指南不允许这样做 但我找不到任何相关的书面信息 有谁知道这写在哪里吗 通常不鼓励使用主页按钮 msdn源 http msdn microsoft c
  • C 中的 Malloc 与结构

    我有一个结构 struct numbers struct char numbers array 1000 struct numbers struct numbers some size 创建struct后 有一个整数作为输入 scanf d
  • 无法在构造函数中分配 this [重复]

    这个问题在这里已经有答案了 我正在尝试合并来自的道具values into this 以下会引发错误 我怎样才能做到这一点 this this values 你可以延长this with 对象 分配 https developer mozi
  • 如何处理自定义 PyYAML 构造函数中的递归?

    PyYAML 可以处理常规 python 对象中的循环图 例如 片段 1 class Node pass a Node b Node a child b b child a We now have the cycle a gt b gt a