python - Python 数据类:如果 __post_init__ 执行类型转换,使用什么类型?
问题描述
我有一个 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
when access的代码。 - 如果我只提供最终
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
to Struct.__init__
。元组、列表和任何其他MyList
可以接受的东西都被传递给Struct.from_iterable
,这将负责构造MyList
要传递给的实例Struct
。
推荐阅读
- c - c、加号结果奇怪
- javascript - 如何解决从 Ace Editor 获得的代码值的 Brython Giving Error
- mysql - Aurora - 大表 - 是 DROP COLUMN 锁定操作
- php - 在 Mongo Laravel 中按价格排序
- sharepoint - 在 Sharepoint 目录中上传图像后,总是得到字母数字 id
- xamarin.android - 无法更改微调器 Xamarin Android 的 textSize
- c# - 如何让 Microsoft.Data.SqlClient 与 DataSet Designer 一起工作?
- javascript - 如何格式化轴标签以在 Chart.js 中显示来自 UNIX 时间戳的格式化日期
- c# - 在 Unity 中放大和缩小
- webpack - 如何在 viteJS 中使用自定义加载器处理 CSS 文件?