【问题标题】:!!python/object:__main__.ClassName throwing exception!!python/object:__main__.ClassName 抛出异常
【发布时间】:2018-02-02 10:36:48
【问题描述】:

我有一个 YAML 文件:./YAML/simpleData.yml

- name: 'Somu'
  age:  26
  content:
  - name: 'Neo'
    age:  27
    content: []
  - name: 'Ari'
    age:  26
    content: []

我正在尝试通过以下方式使用 PyYAML 解析它:

import yaml
# Creating objects directly with the YAML module:
print("Attempting Direct Object Load: ")


class Person:
    def __init__(self, name, age, con):
        self.name = name
        self.age = hp
        self.content = con

    def __repr__(self):
        return "%s(name=%r, hp=%r, sp=%r)" % (
            self.__class__.__name__, self.name, self.age, self.content)

    def printData(self):
        print(self.name)
        print(self.age)
        if self.content:
            for per in self.content:
                print("-->", end="")
                per.printData()


# Data load:
person_obj = None
data = ""
try:
    with open('YAML/simpleData.yml') as source:
        for line in source:
            data += line
except Exception as err:
    print("An exception occurred: " + str(err))

person_obj = yaml.load("""!!python/object:__main__.Person\n""" + data)

if not person_obj:
    print("Data Loading Failed..! EXITING!!")
    exit(1)

person_obj.printData()

我是 Python 新手,因此无法确定我做错了什么,因此引发了此异常:

yaml.constructor.ConstructorError: expected a mapping node, but found sequence
  in "<unicode string>", line 1, column 1:
    !!python/object:__main__.Person
    ^

我该如何解决这个问题?


完整输出转储:

Attempting Direct Object Load: 
Traceback (most recent call last):
  File "/home/somu/Programming/python/HeadFirstPython/yamlIntro.py", line 106, in <module>
    person_obj = yaml.load("""!!python/object:__main__.Person\n""" + data)
  File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/__init__.py", line 72, in load
    return loader.get_single_data()
  File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 37, in get_single_data
    return self.construct_document(node)
  File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 46, in construct_document
    for dummy in generator:
  File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 578, in construct_python_object
    state = self.construct_mapping(node, deep=deep)
  File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 204, in construct_mapping
    return super().construct_mapping(node, deep=deep)
  File "/home/somu/Programming/python/HeadFirstPython/venv/lib/python3.6/site-packages/yaml/constructor.py", line 122, in construct_mapping
    node.start_mark)
yaml.constructor.ConstructorError: expected a mapping node, but found sequence
  in "<unicode string>", line 1, column 1:
    !!python/object:__main__.Person
    ^

Process finished with exit code 1

【问题讨论】:

  • 错误信息说明了一切:需要映射(字典),但您的 YAML 文件包含序列(列表)。
  • @tinita 但是 YAML 模块不知道如何处理 YAML 数组吗?
  • 当然 PyYAML 知道如何处理数组(序列)。但是 Person 对象需要序列化为映射。

标签: python yaml pyyaml


【解决方案1】:

在根源上,c.q.在您的文件的顶层,您有一个序列。其中第一个元素是键值对name:Somu 的映射。

如果你想以你描述的方式使用 PyYAML 加载它,你应该去掉每行的前两个字符:

data += line[2:]

或在第一个破折号后插入!!python/object:__main__.Person

data = data.replace('- ', '- !!python/object:__main__.Person\n', 1)

【讨论】:

    猜你喜欢
    • 2013-05-24
    • 1970-01-01
    • 2013-02-11
    • 2017-08-27
    • 1970-01-01
    • 2022-12-19
    • 2011-05-30
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多