Python多继承时调用父类__init__出现TypeError的pythonic方案问询
报错根因
你遇到的报错是Python多继承的MRO(方法解析顺序)导致的:
你写的super(EventFinder, self).__init__()实际上是调用EventFinder父类的__init__方法,EventFinder的父类是object,而object.__init__只接收self一个参数,你传入pickle_filename和export_path自然会触发类型错误。
规范解决方案
Python多继承的标准协作初始化方式是所有父类都在__init__中接收**kwargs,并将不属于本类的参数通过super().__init__传递给MRO链上的下一个类。修改后的代码如下:
1. 修改基类MetaFunction
class MetaFunction(metaclass=ABCMeta): def __init__( self, pickle_data: PickleData, eth_protocols: Protocols = (), spi_protocols: Protocols = (), **kwargs ): # 处理本类自定义参数 self.pickle_data = pickle_data self.eth_protocols = eth_protocols self.spi_protocols = spi_protocols # 剩余参数传递给MRO下一个类 super().__init__(**kwargs)
2. 修改子类AEB
class AEB(MetaFunction): def __init__( self, pickle_data: PickleData, eth_protocols: Protocols = (), spi_protocols: Protocols = (), **kwargs ): super().__init__( pickle_data=pickle_data, eth_protocols=eth_protocols, spi_protocols=spi_protocols, **kwargs )
3. 修改基类EventFinder
class EventFinder: def __init__(self, pickle_filename, export_path, **kwargs): # 处理本类自定义参数 self.pickle_filename = pickle_filename self.export_path = export_path # 剩余参数传递给MRO下一个类 super().__init__(**kwargs)
4. 最终子类AEBEventFinder写法
只需要一次super()调用即可完成所有父类初始化:
class AEBEventFinder(AEB, EventFinder): def __init__( self, pickle_filename: str, export_path: str, pickle_data: PickleData, eth_protocols: Protocols = (), spi_protocols: Protocols = () ): super().__init__( pickle_filename=pickle_filename, export_path=export_path, pickle_data=pickle_data, eth_protocols=eth_protocols, spi_protocols=spi_protocols )
补充说明
你自己摸索的仅给所有父类加**kwargs、不额外调用super().__init__的方案也可以解决当前场景的报错,但仅适配你当前固定的继承顺序,不属于通用的协作多继承规范写法,后续调整继承顺序或者新增父类时可能会出现参数丢失的问题,更推荐使用上面的标准方案。
内容的提问来源于stack exchange,提问作者Filip Szczybura
相关产品推荐
相关产品推荐

