Python3 threading.Thread回调异常:子类方法未执行,父类抽象方法被调用
问题原因分析与解决思路
首先咱们拆解你遇到的两个核心问题:线程执行时调用抽象类方法而非子类,以及WebSocketApp回调指向父类方法的错误。
1. 为什么线程会调用抽象类的方法?
你遇到的输出None而非3,本质是方法绑定的问题,结合threading.Thread的继承逻辑,常见误区有这两种:
误区一:错误地将父类方法作为线程target传参
如果你的代码是类似这样的写法:
# 错误示例 class BaseClass(threading.Thread): def get_value(self): return None class ChildClass(BaseClass): def get_value(self): return 3 def main(): # 直接把父类方法当target,线程会调用BaseClass的get_value thread = threading.Thread(target=BaseClass.get_value) thread.start() thread.join()
这种方式相当于直接调用父类的未绑定方法,完全没用到子类实例,自然会返回父类的None。
正确的做法是实例化子类后启动线程——因为继承threading.Thread的类,会通过run方法执行逻辑,只要子类重写了对应方法,实例启动后会自动调用子类的实现:
# 正确示例 class BaseClass(threading.Thread): def run(self): self.result = self.get_value() def get_value(self): return None class ChildClass(BaseClass): def get_value(self): return 3 def main(): child_thread = ChildClass() child_thread.start() child_thread.join() print(child_thread.result) # 输出3
误区二:父类中硬编码调用自身方法而非实例方法
如果父类的run方法里是这么写的:
def run(self): # 硬编码调用父类的get_value,而非实例的get_value self.result = BaseClass.get_value(self)
哪怕子类重写了get_value,这里也会强制调用父类的方法,导致输出None。修正的话,直接用self.get_value()即可,Python会自动根据实例类型调用对应的子类方法。
2. WebSocketApp回调错误的原因
你看到的<bound method BaseClass... of <...ChildClass...>>,说明回调函数绑定的是父类的方法,而非子类重写后的版本。问题出在注册回调时的方法引用:
如果在父类的初始化方法里这么写:
# 错误示例 def __init__(self): super().__init__() self.ws = websocket.WebSocketApp( "ws://example.com", on_message=BaseClass.on_message # 直接绑定父类方法 )
哪怕子类重写了on_message,WebSocketApp还是会调用父类的实现。正确的做法是绑定实例自身的方法:
# 正确示例 def __init__(self): super().__init__() self.ws = websocket.WebSocketApp( "ws://example.com", on_message=self.on_message # 绑定实例的方法,会自动指向子类重写后的版本 )
总结核心要点
- 继承
threading.Thread时,一定要通过实例化子类来启动线程,不要直接把父类方法当target。 - 类内部调用方法时,始终用
self.方法名(),不要硬编码父类类名来调用方法,这样才能触发Python的多态特性。 - 注册回调(比如WebSocketApp的回调)时,要绑定实例的方法(
self.xxx),而不是父类的类方法引用。
内容的提问来源于stack exchange,提问作者Uno Yakshi
相关产品推荐
相关产品推荐

