我有一个 Python 类,它的字段可以传递几种序列类型之一。为了简化,我将坚持使用元组和列表。 __init__
将参数转换为 MyList
.
from typing import Union
from dataclasses import dataclass, InitVar, field
class MyList(list):
pass
@dataclass
class Struct:
field: Union[tuple, list, MyList]
def __post_init__(self):
self.field = MyList(self.field)
我应该为
field
使用什么类型宣言?field
始终是 MyList
访问时。 MyList
类型,当我通过时 PyCharm 会提示 Struct()
list
. 我可以改为使用:
_field: InitVar[Union[tuple, list, MyList]] = None
field: MyList = field(init=False)
def __post_init__(self, _field):
self.field = MyList(_field)
但这非常难看,尤其是在 3 个字段中重复时。此外,我必须构建一个结构,如
Struct(_field=field)
而不是 Struct(field=field)
.2018 年 4 月,“tm”在 PyCharm 的公告中对此问题进行了评论:https://blog.jetbrains.com/pycharm/2018/04/python-37-introducing-data-class/#comment-323957
最佳答案
您正在将向属性分配值与生成要分配给属性的值的代码混为一谈。我会使用一个单独的类方法来保持两段代码分开。
from dataclasses import dataclass
class MyList(list):
pass
@dataclass
class Struct:
field: MyList
@classmethod
def from_iterable(cls, x):
return cls(MyList(x))
s1 = Struct(MyList([1,2,3]))
s2 = Struct.from_iterable((4,5,6))
现在,您只需传递一个现有值 MyList
至 Struct.__init__
.元组、列表和其他任何东西 MyList
能接受的都传给Struct.from_iterable
相反,它将负责构建 MyList
传递给 Struct
的实例.
关于Python 数据类 : What type to use if __post_init__ performs type conversion?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51737828/