动态添加字段到数据类对象
Dynamically add fields to dataclass objects
我正在编写一个库来访问 REST API。它 returns json 与用户对象。我将它转换为字典,然后将其转换为数据类对象。问题是并非所有字段都是固定的。我想动态添加其他字段(未在我的数据类中指定)。我可以简单地为我的对象赋值,但它们不会出现在对象表示中并且 dataclasses.asdict
函数不会将它们添加到生成的字典中:
from dataclasses import asdict, dataclass
@dataclass
class X:
i: int
x = X(i=42)
x.s = 'text'
x
# X(i=42)
x.s
# 'text'
asdict(x)
# {'i': 42}
您可以使用 make_dataclass
即时创建 X
:
X = make_dataclass('X', [('i', int), ('s', str)])
x = X(i=42, s='text')
asdict(x)
# {'i': 42, 's': 'text'}
或派生 class:
@dataclass
class X:
i: int
x = X(i=42)
x.__class__ = make_dataclass('Y', fields=[('s', str)], bases=(X,))
x.s = 'text'
asdict(x)
# {'i': 42, 's': 'text'}
如前所述,标记为可选的字段应该可以解决问题。如果没有,请考虑使用 dataclasses
中的属性。是的,常规属性应该工作得很好——尽管你必须在 __post_init__
中声明字段,这有点不方便。
如果您想为 属性 设置默认值,那么在创建对象后立即访问 getter 就可以正常工作,并且如果您还希望能够通过构造函数设置默认值,您可以使用一个称为字段属性的概念; dataclass-wizard 等几个库提供
全力支持。
用法示例:
from dataclasses import asdict, dataclass
from typing import Optional
from dataclass_wizard import property_wizard
@dataclass
class X(metaclass=property_wizard):
i: int
s: Optional[str] = None
@property
def _s(self):
return self._s
@_s.setter
def _s(self, s: str):
self._s = s
x = X(i=42)
x.s = 'text'
x
# X(i=42, s='text')
x.s
# 'text'
asdict(x)
# {'i': 42, 's': 'text'}
免责声明:我是这个库的创建者(和维护者)。
我正在编写一个库来访问 REST API。它 returns json 与用户对象。我将它转换为字典,然后将其转换为数据类对象。问题是并非所有字段都是固定的。我想动态添加其他字段(未在我的数据类中指定)。我可以简单地为我的对象赋值,但它们不会出现在对象表示中并且 dataclasses.asdict
函数不会将它们添加到生成的字典中:
from dataclasses import asdict, dataclass
@dataclass
class X:
i: int
x = X(i=42)
x.s = 'text'
x
# X(i=42)
x.s
# 'text'
asdict(x)
# {'i': 42}
您可以使用 make_dataclass
即时创建 X
:
X = make_dataclass('X', [('i', int), ('s', str)])
x = X(i=42, s='text')
asdict(x)
# {'i': 42, 's': 'text'}
或派生 class:
@dataclass
class X:
i: int
x = X(i=42)
x.__class__ = make_dataclass('Y', fields=[('s', str)], bases=(X,))
x.s = 'text'
asdict(x)
# {'i': 42, 's': 'text'}
如前所述,标记为可选的字段应该可以解决问题。如果没有,请考虑使用 dataclasses
中的属性。是的,常规属性应该工作得很好——尽管你必须在 __post_init__
中声明字段,这有点不方便。
如果您想为 属性 设置默认值,那么在创建对象后立即访问 getter 就可以正常工作,并且如果您还希望能够通过构造函数设置默认值,您可以使用一个称为字段属性的概念; dataclass-wizard 等几个库提供 全力支持。
用法示例:
from dataclasses import asdict, dataclass
from typing import Optional
from dataclass_wizard import property_wizard
@dataclass
class X(metaclass=property_wizard):
i: int
s: Optional[str] = None
@property
def _s(self):
return self._s
@_s.setter
def _s(self, s: str):
self._s = s
x = X(i=42)
x.s = 'text'
x
# X(i=42, s='text')
x.s
# 'text'
asdict(x)
# {'i': 42, 's': 'text'}
免责声明:我是这个库的创建者(和维护者)。