python - 包含属性的 python 类的 ruamel.yaml 转储似乎会产生意外的 yaml 格式
问题描述
我正在将 python 类数据转储到 YAML,以便稍后加载。我发现使用 ruamel.yaml(和 PyYAML),当我使用属性转储类来管理类属性时,YAML 输出更改为似乎无效的 YAML 语法。我把下面的代码放在一起来演示行为
import sys
import ruamel.yaml
class MySampleClass(object):
def __init__(self, attribute1, attribute2):
self.attribute1 = attribute1
self.attribute2 = attribute2
@property
def attribute1(self):
return self.attribute1
@attribute1.setter
def attribute1(self, attribute1):
self.__attribute1 = attribute1
sample1 = MySampleClass("ABCD", "123")
yaml = ruamel.yaml.YAML()
yaml.register_class(MySampleClass)
yaml.dump(sample1, sys.stdout)
运行时会产生以下输出。如您所见,装饰的第一个属性具有意外的格式,而第二个属性是 YAML 所期望的。
!MySampleClass
_MySampleClass__attribute1: ABCD
attribute2: '1234'
有没有办法在不从头开始为每个类编写自定义构造函数和表示器的情况下克服这个问题?
解决方案
ruamel.yaml
不将属性/设置器作为“普通”属性处理,这就是为什么你会得到有趣的输出,这是有效的 YAML。
首先,尽管您应该更改您的 attribute1 属性,因为调用print(sample1.attribute1)
将使您进入无限递归。
然后,您可以只创建一个基类,该基类具有to_yaml
可用于转储所有类的适当方法:
import sys
import ruamel.yaml
yaml = ruamel.yaml.YAML()
class ObjWithProperties(object):
@classmethod
def to_yaml(cls, representer, node):
tag = getattr(cls, 'yaml_tag', '!' + cls.__name__)
attribs = {}
for x in dir(node):
if x.startswith('_'):
continue
v = getattr(node, x)
if callable(v):
continue
attribs[x] = v
return representer.represent_mapping(tag, attribs)
@yaml.register_class
class MySampleClass(ObjWithProperties):
def __init__(self, attribute1, attribute2):
self.attribute1 = attribute1
self.attribute2 = attribute2
@property
def attribute1(self):
return self.__attribute1 # <<<< note the added double underscore to prevent recursion
@attribute1.setter
def attribute1(self, attribute1):
self.__attribute1 = attribute1
sample1 = MySampleClass("ABCD", "123")
yaml.dump(sample1, sys.stdout)
这使:
!MySampleClass
attribute1: ABCD
attribute2: '123'
推荐阅读
- css - 需要帮助来确定第 n 个孩子的价值
- swift - 我可以从一个 VC 的标签中获取数据并将数据从另一个 VC 传递到文本字段吗
- spring-security - 带有 JWT 自定义 UserDetails 的 Spring OAuth - 在 JwtAccessTokenConverter 中设置主体
- spring - 启用子资源级别弹簧数据休息?
- c# - WPF:绑定到绑定模式
- android - 改造 + Gson DateFormat 不起作用
- nunit - 如何使用 Sparx Enterprise Architect 为 NUnit 项目自动生成序列图
- c# - SharingCapability SharePoint Online 网站集 c#
- android-studio - ADB.exe 已过时且存在严重的性能问题
- mysql - 在 Ubuntu 上使用 phpmyadmin 设置绝对 url