Dataclass继承变量异常:子类传参触发TypeError多值参数错误
数据类子类重写__init__后出现TypeError的解决办法
问题描述
定义了带kw_only字段的ZooAnimals数据类,实例化传参正常,但子类Cats重写__init__后,调用构造函数时报错:TypeError: Cats.__init__() got multiple values for argument 'name'。
原父类代码:
@dataclass class ZooAnimals(): food_daily_kg: int price_food: float area_required: float name: str = field(default='Zebra', kw_only=True) c = ZooAnimals(565, 40, 10, name='Monkey') # 输出: ZooAnimals(food_daily_kg=565, price_food=40, area_required=10, name='Monkey')
原子类代码:
@dataclass class Cats(ZooAnimals): def __init__(self, food_daily_kg, price_food, area_required, name, meowing): meowing: str super().__init__() z = Cats(465, 30, 10, 'Little Bit', name='Leopard') # 触发错误: TypeError: Cats.__init__() got multiple values for argument 'name'
错误原因
- 重复传参:子类
__init__把name设为位置参数,调用时'Little Bit'已经通过位置赋值给name,后面又用name='Leopard'传关键字参数,导致同一个参数被赋值两次,触发类型错误。 - 子类__init__写法错误:
meowing的类型注解写在了函数内部,不符合Python语法;且调用super().__init__()时未传递任何参数,父类的必填字段会因未赋值引发后续错误。 - 与父类设计冲突:父类
name是kw_only=True的关键字专属参数,但子类将其设为位置参数,打破了原有传参规则,导致传参逻辑混乱。
解决方法
方法一:利用数据类自动生成__init__(推荐)
数据类的核心优势是自动生成__init__等方法,尽量避免手动重写,直接添加子类字段即可:
from dataclasses import dataclass, field @dataclass class ZooAnimals(): food_daily_kg: int price_food: float area_required: float name: str = field(default='Zebra', kw_only=True) @dataclass class Cats(ZooAnimals): meowing: str # 直接添加子类字段,dataclass自动处理构造逻辑 # 调用方式:前三个为位置参数,name和meowing用关键字参数 z = Cats(465, 30, 10, name='Leopard', meowing='Miao') print(z) # 输出: Cats(food_daily_kg=465, price_food=30, area_required=10, name='Leopard', meowing='Miao')
方法二:手动重写__init__(需规范参数逻辑)
若必须手动重写,需确保参数规则与父类一致,并正确传递参数给父类:
from dataclasses import dataclass, field @dataclass class ZooAnimals(): food_daily_kg: int price_food: float area_required: float name: str = field(default='Zebra', kw_only=True) @dataclass class Cats(ZooAnimals): def __init__(self, food_daily_kg: int, price_food: float, area_required: float, *, name: str = 'Zebra', meowing: str): # 用*分隔位置参数与关键字参数,确保name为关键字专属参数,和父类规则一致 super().__init__( food_daily_kg=food_daily_kg, price_food=price_food, area_required=area_required, name=name ) self.meowing = meowing # 调用时name必须用关键字参数 z = Cats(465, 30, 10, name='Leopard', meowing='Miao') print(z) # 输出: Cats(food_daily_kg=465, price_food=30, area_required=10, name='Leopard', meowing='Miao')
内容的提问来源于stack exchange,提问作者user4718221
相关产品推荐
相关产品推荐

