首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ruamel.yaml无法处理NamedTuple

ruamel.yaml无法处理NamedTuple
EN

Stack Overflow用户
提问于 2022-11-23 04:41:19
回答 1查看 15关注 0票数 0

所以我有下面的代码:

代码语言:javascript
复制
import sys
from typing import NamedTuple

import ruamel.yaml as ryaml


class Loc(NamedTuple):
    lat: float
    long: float


data = {
    "APAC": {
        "rating": 5,
        "leads": ["Jane", "John"],
        "locs": [Loc(1.0, 1.0), Loc(2.0, 2.0)],
    },
    "EMEA": {
        "rating": 5,
        "leads": ["Jane", "Jack"],
        "locs": [Loc(3.0, 3.0), Loc(4.0, 4.0)],
    }
}


def main():
    # Just to check that Loc is indeed recognized as a tuple
    assert all(map(lambda o: isinstance(o, tuple), data["APAC"]["locs"]))
    assert all(map(lambda o: isinstance(o, tuple), data["EMEA"]["locs"]))

    yml = ryaml.YAML()
    yml.register_class(Loc)
    yml.dump(data, sys.stdout)


if __name__ == '__main__':
    main()

但是,每当我执行代码时,我都会得到一系列的异常,结尾是:

代码语言:javascript
复制
  File "C:\Repos\@Venv\myproj-cpy3.11-1\Lib\site-packages\ruamel\yaml\representer.py", line 1090, in represent_yaml_object
    anchor = state.pop(Anchor.attrib, None)
             ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'pop'

如果我使用'bare‘tuple而不是Loc(),错误就不会出现。

我如何使ruamel.yaml理解Loc是一个NamedTuple是一个tuple

我用的是CPython 3.11ruamel.yaml==0.17.21

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-23 06:48:49

由于某种原因,您注册了Loc类,但您没有告诉ruamel.yaml如何转储该类,并且该信息不会自动添加,而且相对较新的特性(如NamedTupleDataClasses(没有被ruamel.yaml代码基以特殊方式显式识别和处理)(如果是的话,它们甚至可能不需要注册倾销,但它们可能需要加载)。

文档中的示例显示,这是为已注册的类完成的,即通过添加一个to_yaml类方法,所以您也需要对Loc这样做。

代码语言:javascript
复制
import sys
from typing import NamedTuple
import ruamel.yaml

class Loc(NamedTuple):
    lat: float
    long: float

    @classmethod
    def to_yaml(cls, representer, node):
        return representer.represent_sequence('!Loc', node)
 
data = {
    "APAC": {
        "rating": 5,
        "leads": ["Jane", "John"],
        "locs": [Loc(1.0, 1.0), Loc(2.0, 2.0)],
    },
    "EMEA": {
        "rating": 5,
        "leads": ["Jane", "Jack"],
        "locs": [Loc(3.0, 3.0), Loc(4.0, 4.0)],
    }
}

def main():
    assert all(map(lambda o: isinstance(o, tuple), data["APAC"]["locs"]))
    assert all(map(lambda o: isinstance(o, tuple), data["EMEA"]["locs"]))

    yaml = ruamel.yaml.YAML()
    yaml.register_class(Loc)
    yaml.dump(data, sys.stdout)

main()

这意味着:

代码语言:javascript
复制
APAC:
  rating: 5
  leads:
  - Jane
  - John
  locs:
  - !Loc
    - 1.0
    - 1.0
  - !Loc
    - 2.0
    - 2.0
EMEA:
  rating: 5
  leads:
  - Jane
  - Jack
  locs:
  - !Loc
    - 3.0
    - 3.0
  - !Loc
    - 4.0
    - 4.0
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74541869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档