[英]Python dataclass to implement choice type
我有一组数据类说:
from dataclasses import dataclass, asdict, InitVar
@dataclass
class Item:
name: str = None
identifier: int = None
@dataclass
class Container:
item: Item
cid: int
cname: str = None
当我做:
c = Container(Item(name="item-1"), cid=10)
asdict(c)
我得到:
{'item': {'name': 'item-1', 'identifier': None},'cid': 10,'cname': None}
但在我的模式中, Item是“选择”类型,所以我只想在“asdict”中包含“名称”或“标识符”,具体取决于实际设置的那些(仅适用于 Item 类型)。
就像是:
{'item': {'name': 'item-1'},'cid': 10,'cname': None}
或者:
{'item': {'identifier': 'id-1'},'cid': 10,'cname': None}
我的原始代码要复杂得多,而且关系更加嵌套,所以我正在寻找一种可以应用于特定数据类的解决方案。 我尝试操纵__dict__
以在__post_init__
中添加属性,但这没有用。 例如我试过
from dataclasses import dataclass, asdict, InitVar
@dataclass
class Item:
name: InitVar[str] = None
identifier: InitVar[int] = None
def __post_init__(self, name, identifier):
if name:
self.name = name
elif identifier:
self.identifier = identifier
print(self.__dict__)
@dataclass
class Container:
item: Item
identifier: int
cname: str = None
c = Container(Item(name="item-1"), cid=10)
asdict(c)
但那会打印
{'item': {}, 'cid': 10, 'cname': None}
这可能不是您想要的,但此时,当您想要数据类的自定义dict
表示时,唯一的.asdict
dataclass
。
这是一个建议的起点(可能需要调整):
from dataclasses import dataclass, asdict
@dataclass
class DataclassAsDictMixin:
def asdict(self):
d = asdict(self)
for field, value in ((f,v) for f,v in vars(self).items() if f in d):
try:
value = value.asdict()
except AttributeError:
pass
else:
d.update([(field, value)])
return d
@dataclass
class Item:
name: str = None
identifier: int = None
def asdict(self):
d = asdict(self)
for k,v in d.copy().items():
if v is None:
del d[k]
return d
@dataclass
class Container(DataclassAsDictMixin):
item: Item
cid: int
cname: str = None
if __name__ == "__main__":
c1 = Container(Item(name="item-1"), cid=10)
assert c1.asdict() == {'item': {'name': 'item-1'}, 'cid': 10, 'cname': None}
c2 = Container(Item(identifier="id-1"), cid=10)
assert c2.asdict() == {'item': {'identifier': 'id-1'}, 'cid': 10, 'cname': None}
我没有使用值列表对其进行测试,但请尝试以下方法:
from copy import copy
from dataclasses import dataclass, fields
from validated_dc import ValidatedDC
@dataclass
class Base(ValidatedDC):
def is_correct_value(self, value):
return True
def as_dict(self):
result = {}
nested = tuple(self.get_nested_validated_dc())
for field in fields(self):
value = copy(getattr(self, field.name))
if isinstance(value, list):
for item in value:
if isinstance(item, nested):
item = item.as_dict()
if isinstance(value, nested):
value = value.as_dict()
if self.is_correct_value(value):
result[field.name] = value
return result
@dataclass
class ItemBase(Base):
def is_correct_value(self, value):
return False if value is None else True
@dataclass
class Item(ItemBase):
name: str = None
identifier: int = None
@dataclass
class Container(Base):
item: Item
cid: int
cname: str = None
c = Container(Item(name="item-1"), cid=10)
assert c.as_dict() == {'item': {'name': 'item-1'}, 'cid': 10, 'cname': None}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.