如何从运行在threading线程中的自定义类获取成员变量?
问题原因
你遇到的AttributeError本质是两个问题叠加导致的:
threading.Thread实例和你要运行的mysubclass实例是完全独立的两个对象,你将mysubclass作为target传入线程后,线程执行时只会调用该类完成实例化,不会自动将生成的实例挂载到Thread对象上,自然无法从self.thread上取到var属性。- 就算你持有了
mysubclass实例的引用,也要保证线程已经完成__init__方法执行、var属性初始化完成后再读取,否则仍然可能出现属性不存在的错误。
可行解决方案
下面给出两种常用的实现方式:
方案1:提前实例化子类,持有引用后交给线程运行
如果你的子类逻辑可以拆分初始化和运行逻辑,推荐用这种写法,逻辑最清晰:
import threading class myclass: class mysubclass: def __init__(self): # 初始化变量 self.var = "anything" def run(self): # 这里放子类需要在线程中执行的耗时逻辑 pass def __init__(self): # 先完成子类初始化,直接持有实例引用 self.sub_inst = self.mysubclass() # 线程只负责执行子类的运行逻辑 self.thread = threading.Thread(target=self.sub_inst.run) self.thread.start() # 可根据需要调用join等待线程执行完成,确保读取属性时是最终值 self.thread.join() # 直接从持有的实例引用中取变量 print(self.sub_inst.var) myclass()
方案2:通过可变容器传递线程内生成的实例
如果子类的初始化逻辑必须在线程中执行,可以用列表/字典这类可变容器传递实例:
import threading class myclass: class mysubclass: def __init__(self): self.var = "anything" def __init__(self): # 用列表做容器,方便线程内修改后外层可以读取 sub_container = [] def thread_task(): # 线程内完成子类实例化 sub_inst = self.mysubclass() sub_container.append(sub_inst) self.thread = threading.Thread(target=thread_task) self.thread.start() # 等待线程执行完成,确保实例已经存入容器 self.thread.join() # 从容器中取出实例后读取变量 self.sub_inst = sub_container[0] print(self.sub_inst.var) myclass()
注意事项
- 不要尝试直接在
Thread实例上挂载自定义业务属性,Thread对象仅负责线程调度,和业务逻辑解耦是更合理的实现方式 - 跨线程读写变量一定要做好同步,可通过
join()等待线程执行完成、或者加threading.Lock锁的方式避免竞态条件,防止读取到未初始化的异常值。
内容的提问来源于stack exchange,提问作者thepancakeplant
相关产品推荐
相关产品推荐

