如何覆写Python类字典中存储的成员函数 无需透传函数即可生效
问题解答
问题1:无透传函数时覆写不生效的原因
你在类定义阶段写入msgConfig字典的是基类函数的直接引用,属于未绑定的普通函数对象,和后续子类覆写的set_enable是两个完全独立的函数引用,字典里的引用不会随子类覆写自动更新。
调用self.msgConfig[msg](self)时,是直接执行字典里存储的基类函数,不会走Python正常的实例方法查找流程(即MRO继承解析),因此永远调用的是基类实现。
透传函数生效的核心原因是:透传函数内调用的是self.set_enable,这是标准的实例属性访问,会自动按照MRO顺序查找当前实例对应的类的方法实现,因此能触发多态,调到子类覆写后的函数。
问题2:符合要求的解决方案
最简单的实现方式是将配置字典中的值从函数对象改为方法名字符串,收到消息时通过getattr从实例上动态获取对应方法,天然支持继承多态,既不需要透传函数,也不需要在子类初始化时追加覆写的方法到字典。
修改后的核心代码如下:
class Base(): def set_enable(self): print("In base class set_enable") # 配置字典存方法名,而非直接存函数引用 msgConfig = { 'setEnable': 'set_enable', } def __init__(self, msgConfig=None): if msgConfig: self.msgConfig.update(msgConfig) def msg_recived(self, msg, *args, **kwargs): # 从实例动态取方法,自动走MRO查找 func_name = self.msgConfig[msg] func = getattr(self, func_name) # 支持透传任意参数 return func(*args, **kwargs) class Child(Base): # 直接覆写即可,无需修改任何配置 def set_enable(self, data = None, header=None): print("In child class set_enable") def disconnect(self, data = None, header=None): print("In child class disconnect_connection") BtMsgs = { 'disconnect': 'disconnect', } def __init__(self): Base.__init__(self, Child.BtMsgs)
测试验证:
if __name__ == "__main__": child = Child() child.msg_recived('disconnect') # 现在会直接调用子类覆写的set_enable,无需透传函数 child.msg_recived('setEnable')
输出结果:
In child class disconnect_connection In child class set_enable
内容的提问来源于stack exchange,提问作者awinner
相关产品推荐
相关产品推荐

