如何使继承dataclass的Pointer子类保持指定构造参数顺序?
保留冻结dataclass子类的原有参数顺序
当然可以保留原有参数顺序,有两种直接的解决方式:
方法一:调整类内字段定义顺序(推荐)
Python的@dataclass会严格按照类中字段定义的先后顺序生成__init__的参数列表。你只需要在Pointer类中把basetype字段写在size字段前面,自动生成的构造函数参数顺序就会和原有代码完全一致:
from dataclasses import dataclass @dataclass(frozen=True) class Type: # 父类的字段定义(如果有的话) pass @dataclass(frozen=True) class Pointer(Type): # 把basetype放在size前面,对应原构造函数的参数顺序 basetype: Type size: int # 子类自有字段
这样生成的Pointer.__init__参数顺序就是basetype在前、size在后,800多处调用代码无需任何修改,直接兼容。
方法二:手动实现构造函数(适用于无法调整字段顺序的场景)
如果因为业务逻辑或其他限制不能调整字段顺序,可以给dataclass指定init=False,然后手动编写符合原有参数顺序的__init__方法。注意冻结dataclass的实例无法直接赋值属性,需要用object.__setattr__来完成属性初始化:
from dataclasses import dataclass @dataclass(frozen=True) class Type: pass @dataclass(frozen=True, init=False) class Pointer(Type): # 字段顺序可以保持原有(比如size在前) size: int basetype: Type def __init__(self, basetype: Type, size): # 先调用父类的构造函数(如果父类需要参数,自行传入) super().__init__() # 用object.__setattr__绕过冻结限制,初始化属性 object.__setattr__(self, 'basetype', basetype) object.__setattr__(self, 'size', size)
这种方式完全自定义构造逻辑,参数顺序完全匹配原有代码,同时保留冻结dataclass的不可变特性。
内容的提问来源于stack exchange,提问作者Nordwald
相关产品推荐
相关产品推荐

