Python动态继承场景下如何向combo函数传入coms_type参数
问题核心原因
你现在的实现里reg_map的继承关系是模块导入阶段就固定死的:Python运行到class reg_map(coms_t if coms_type else coms_f)这行时,会直接读取当时顶层作用域的coms_type值确定父类,类定义完成后再修改顶层coms_type不会改动已经生成的reg_map类的继承链,自然没法在调用combo时动态切换通信实现。
实现方案
用动态类组装的思路即可,不需要额外独立配置文件,所有原有业务逻辑都能保留,修改量很小:把原本绑定固定继承关系的类拆成逻辑实现部分,在combo函数被调用、拿到传入的coms_type参数时,再动态拼接出对应继承链的类生成实例。
改造后代码
from telnetcoms import coms as coms_t from ftdicoms import coms as coms_f # 抽离reg_map的通用寄存器操作逻辑,不绑定固定通信父类 class _RegMapCore: def set_chip_register(self, reg_name, reg_value): print('reg_map') reg_num = self.extract_reg_info(reg_name) self.write_reg(reg_num, reg_value) def read_chip_register(self, reg_name, reg_value): print('reg_map') reg_num = self.extract_reg_info(reg_name) self.read_reg(reg_num, reg_value) # 抽离两个芯片的专属业务逻辑,不绑定固定reg_map父类 class _Chip1Core: def __init__(self): pass def dev_func(self): print('chip1') self.set_chip_register(reg_name, reg_value) class _Chip2Core: def __init__(self): pass def dev_func(self): print('chip2') self.set_chip_register('some_reg_name', reg_value) def combo(chip_type, coms_type=0): # 根据传入参数选择对应通信实现类 coms_impl = coms_t if coms_type else coms_f # 动态生成绑定了当前通信实现的reg_map类 class LiveRegMap(_RegMapCore, coms_impl): pass # 根据芯片类型动态组装最终类,返回实例 if chip_type == 'chip1': class LiveChip1(_Chip1Core, LiveRegMap): pass return LiveChip1() if chip_type == 'chip2': class LiveChip2(_Chip2Core, LiveRegMap): pass return LiveChip2() raise ValueError(f"不支持的芯片类型: {chip_type}") # 完全符合预期的调用方式 myclass = combo('chip1', coms_type=0) myclass.set_chip_register('some_reg_name', 25) # 同一进程内可以同时生成不同通信方式的实例,互不干扰 myclass_ftdi = combo('chip2', coms_type=1)
方案说明
- 原有寄存器操作、芯片业务逻辑、底层通信方法完全不需要改动,只是把静态的类继承改成了调用时动态组装
- 不同参数生成的实例完全隔离,就算同一次测试流程里需要同时用telnet和I2C连接不同芯片也能正常运行
- 如果偏好
type语法创建类,也可以把函数内动态定义类的部分换成type实现,效果完全一致:LiveRegMap = type('LiveRegMap', (_RegMapCore, coms_impl), {}) - 原代码里
chip1.dev_func方法使用的reg_name、reg_value变量未定义,是原有逻辑的bug,和继承实现无关,使用时需要补全参数。
内容的提问来源于stack exchange,提问作者Nick Smith
相关产品推荐
相关产品推荐

