Python NamedTuple子类from_instruction方法报错:参数数量不符
解决
OrderedInstruction.from_instruction的参数错误问题 这个问题我之前也碰到过,核心原因是你对NamedTuple的继承方式理解有误——直接继承NamedTuple子类并添加新字段的写法,并不会把新字段自动纳入NamedTuple的字段体系里,导致OrderedInstruction的__new__方法仍然只接受父类Instruction的4个字段参数,最终引发参数数量不匹配的错误。
错误原因详解
你定义的OrderedInstruction继承自Instruction(一个NamedTuple),然后添加了order: int属性。但NamedTuple是基于元组实现的,新增的order只是普通的实例属性,不会被整合到NamedTuple的字段结构中。因此:
OrderedInstruction的__new__方法仍然和父类一致,只接受cls + 4个字段参数,总共5个位置参数- 你在
from_instruction里传入了instruction的4个字段 + order,加上cls就变成了6个位置参数,超出了__new__的预期,所以抛出TypeError: __new__() takes 5 positional arguments but 6 were given
两种正确的解决方法
方法1:重新定义包含所有字段的NamedTuple
不直接继承Instruction,而是重新定义OrderedInstruction为包含Instruction所有字段+order的新NamedTuple,通过_asdict()复用父类实例的字段:
from typing import NamedTuple class Instruction(NamedTuple): function: str argument_register_1: str argument_register_2: str result_register: str class OrderedInstruction(NamedTuple): # 完整包含父类的所有字段 + 新增的order function: str argument_register_1: str argument_register_2: str result_register: str order: int @classmethod def from_instruction(cls, instruction: Instruction, order: int): # 用_asdict()解包父类实例的字段,再传入order return cls(**instruction._asdict(), order=order)
方法2:改用dataclasses实现继承
dataclass对继承的支持更灵活,可以直接继承NamedTuple并添加新字段,不需要重新定义所有父类字段:
from typing import NamedTuple from dataclasses import dataclass class Instruction(NamedTuple): function: str argument_register_1: str argument_register_2: str result_register: str @dataclass class OrderedInstruction(Instruction): order: int @classmethod def from_instruction(cls, instruction: Instruction, order: int): # 直接解包父类实例的字段,加上order即可 return cls(*instruction, order=order)
两种方法都能解决你的问题,你可以根据自己的代码场景选择:如果需要保持NamedTuple的不可变性和元组特性,选方法1;如果更看重继承的简洁性,选方法2。
内容的提问来源于stack exchange,提问作者Comfy Cat
相关产品推荐
相关产品推荐

