问题在于
默认的__init__
实现使用带有冻结类的object.__setattr__()
,如果提供自己的实现,则必须使用它,这会使您的代码相当混乱:
@dataclass(frozen=True, init=False)
class Tricky:
thing1: int
thing2: str
def __init__(self, thing3):
object.__setattr__(self, "thing3", thing3)
不幸的是,Python没有提供使用默认实现的方式,因此我们不能简单地执行以下操作:
@dataclass(frozen=True, init=False)
class Tricky:
thing1: int
thing2: str
def __init__(self, thing3, **kwargs):
self.__default_init__(DoSomething(thing3), **kwargs)
然而,我们可以很容易地实现这种行为:
def dataclass_with_default_init(_cls=None, *args, **kwargs):
def wrap(cls):
user_init = getattr(cls, "__init__")
delattr(cls, "__init__")
result = dataclass(cls, *args, **kwargs)
setattr(result, "__default_init__", result.__init__)
setattr(result, "__init__", user_init)
if result is not cls:
setattr(cls, "__init__", user_init)
return result
if _cls is None:
return wrap
else:
return wrap(_cls)
然后
@dataclass_with_default_init(frozen=True)
class DataClass:
value: int
def __init__(self, value: str):
self.__default_init__(value=int(value))
更新:我打开了这个bug,希望在3.9之前实现。
__hash__
,因为您并没有真正使用dataclass...” - juanpa.arrivillagaself.thing3
是从哪里来的? - vb_rises@dataclass
语法甚至不是特定于数据类的,它只是使用标准注释和类型提示。采用数据类解决了什么问题? - Martijn Pietersunsafe_hash=True
而不是frozen=True
。 - Martijn Pieters