[英]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.