我使用的是python库中的一个函数,它返回具有特定数据类型的对象。我想将该对象序列化为一个yaml文件,我想使用ruamel.yaml。问题是ruamel.yaml
不知道如何序列化函数返回的特定数据类型并引发异常:
RepresenterError: cannot represent an object: <...>
问题是如何将数据类型“声明”为ruamel.yaml
,以便它知道如何处理它。在
注意:我不能/我不想更改库或任何类似的内容。我只是API的消费者。在
为了使其更具体,让我们使用下面的示例,它使用^{
这就产生了这个错误:
ruamel.yaml.YAML.dump(self, data, stream, **kw)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/main.py", line 439, in dump
return self.dump_all([data], stream, _kw, transform=transform)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/main.py", line 453, in dump_all
self._context_manager.dump(data)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/main.py", line 801, in dump
self._yaml.representer.represent(data)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 84, in represent
node = self.represent_data(data)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 111, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 359, in represent_dict
return self.represent_mapping(u'tag:yaml.org,2002:map', data)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 222, in represent_mapping
node_value = self.represent_data(item_value)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 121, in represent_data
node = self.yaml_representers[None](self, data)
File "/home/feanor/Prog/git/vps-bench/.direnv/python-venv-3.7.2/lib/python3.7/site-packages/ruamel/yaml/representer.py", line 392, in represent_undefined
raise RepresenterError('cannot represent an object: %s' % data)
ruamel.yaml.representer.RepresenterError: cannot represent an object: AddressFamily.AF_INET
为了使
ruamel.yaml
能够转储一个特定的类,无论您定义它,您都会得到它 从标准库或从其他地方获取if,您需要针对representer注册该类。 (在使用YAML(typ='unsafe')
时,这是不必要的,但我假设您不想使用它)。在这种注册可以用不同的方式进行。假设你有 完成},并且想要表示
yaml = ruamel.yaml.YAML()
或{SomeClass
,您可以:yaml.register_class(SomeClass)
。这可能适用于其他类,具体取决于 他们是如何定义的。在@yaml_object(yaml)
或{class SomeClass:
之前 定义。这主要用于定义自己的类前两种方法只是在第三种方法的基础上加上了语法糖 他们将尝试使用一个方法
to_yaml
和一个class属性yaml_tag
如果可用,那么尝试做一些合理的事情 无法使用的。在您可以尝试
yaml.register(socket.AF_INET)
,但您会注意到它失败的原因是:所以你必须求助于第三种方法
add_representer()
。参数some_class_to_yaml
是一个函数 会的 当遇到SomeClass
实例时调用,并调用该函数 使用yaml.representer
实例作为第一个参数,并使用实际数据 (SomeClass
的实例)作为第二个参数。在如果
SomeClass
是某种容器类型,可以递归地(间接地)引用自身, 您需要特别注意处理这种可能性,但对于socket.AF_INET
来说,这是不必要的。在到目前为止,特定的数据类型非常重要,您需要决定 如何在YAML中表示类型。你会经常看到的
SomeClass
的属性被用作映射中的键(然后是它 是获取标记的映射),但有时类型可以是 直接表示为YAML中可用的非集合类型,例如 作为一个字符串、int等,对于其他类来说,它是更有意义的 表示为(标记的)序列。在当您打印
type(socket.AF_INET)
时,您会注意到“SomeClass”实际上是AddressFamily
。 在使用dir()
检查socket.AF_INET
之后,您会注意到有一个name
属性,并且 这很好地为您提供了一个字符串'AF_INET'
,它可以用来告诉representer 如何将此数据表示为字符串,而不必进行查找:它给出了:
^{pr2}$确保标记被定义为unicode(在使用python2.7时是必需的)。在
如果您还想加载这个,您可以用类似的方式扩展
^{3}$constructor
。但是 这次您将得到一个Node
,您需要将其转换为AddressFamily
实例。在它运行时不会引发异常,并显示另一个 也处理
socket
中的常量。在相关问题 更多 >
编程相关推荐