首页 > 解决方案 > 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: 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

标签: pythonpython-dataclasses

解决方案


您将向属性分配值与生成要分配给属性的值的代码混为一谈。我会使用一个单独的类方法来将两段代码分开。

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))

现在,您传递一个现有值MyListto Struct.__init__。元组、列表和任何其他MyList可以接受的东西都被传递给Struct.from_iterable,这将负责构造MyList要传递给的实例Struct


推荐阅读