Fib*_*bra 5 python yaml ruamel.yaml
我有两个数据类:Msg和Field。Msg 有一个fields类型字段list[Field]。我想在它们全部初始化后为每个字段分配一些内容,Field这或多或少是它们在列表中的相对索引fields。
但是,当我__post_init__(self)向Msg数据类添加方法时,fields列表为空,因此我无法更新索引。
from dataclasses import dataclass
from ruamel.yaml import YAML
@dataclass
class Msg:
id: int
desc: str
fields: list[Field]
def __post_init__(self) -> None:
idx: int = 0
for field in self.fields: # why is this empty??
field.index = idx
idx += field.size
@dataclass
class Field:
id: int
name: str
units: str
size: int
index: int = -1
y = YAML()
y.register_class(Msg)
y.register_class(Field)
msg: Msg = y.load("""\
!Msg
id: 1
desc: status
fields:
- !Field
id: 1
name: Temp
units: degC
size: 2
""")
assert(msg.fields[0].index != -1) # fails :(
Run Code Online (Sandbox Code Playgroud)
为什么是这样?Msg未初始化的情况下如何初始化fields?有什么办法可以使用班级系统来做我想做的事情吗?我在 MacOS 上使用 Python 3.11 和 ruamel.yaml 0.18.5。
默认情况下,对象序列化程序(例如 YAML)pickle不知道如何处理用户定义对象的属性映射,除了按原样将映射直接分配给对象的属性字典之外。
这就是为什么您可以__setstate__为您的类定义一个方法,以便ruamel.yaml在这种情况下,对象构造函数知道使用__init__解包为参数的映射来调用该方法,这反过来又调用__post_init__后初始化:
@dataclass
class Msg:
id: int
desc: str
fields: list[Field]
def __post_init__(self) -> None:
idx: int = 0
for field in self.fields:
field.index = idx
idx += field.size
def __setstate__(self, state):
self.__init__(**state)
Run Code Online (Sandbox Code Playgroud)
演示:https: //replit.com/@blhsing1/PowerfulThoseJavadocs
| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |