如何向threading.Thread传参至类方法且不覆盖类self?
解决线程调用类方法时self被覆盖的问题
你的问题核心是没有正确传递类实例到线程调用的方法中,同时创建的Map实例没有保存引用直接被销毁了,导致后续调用出错。
问题原因
- 你直接使用
Map.second作为线程目标,这是类的未绑定方法,第一个参数必须是Map类的实例(也就是self),但你传了_(看起来是个字符串占位符),导致self被替换成了字符串对象,自然会报「str对象没有fig属性」。 - 你创建的
Map()实例没有保存到变量里,执行完这行代码后实例就被垃圾回收了,就算参数传对了也找不到self.fig。
修正方案
方案1:用实例绑定的方法作为线程目标(推荐)
先保存Map实例,然后直接把实例的second方法作为线程目标,此时self会自动绑定,args只需要传方法的其他参数:
import threading class Map(): def __init__(self): self.fig = load('HugeFig') # 假设load是你已实现的加载方法 def second(self, arg1, arg2): # 这里添加范围设置逻辑 self.fig.show() # 保存HTML的逻辑示例 # self.fig.write_html(f"subplot_{arg1}_{arg2}.html") class Main(): def run(self): # 保存Map实例,避免创建后直接被回收 map_instance = Map() # 用实例的绑定方法作为线程目标,args仅传递方法所需的arg1、arg2 thread = threading.Thread(target=map_instance.second, args=(arg1, arg2)) thread.start() # 启动线程 # thread.join() # 如果需要等待线程执行完成,可添加此行 if __name__ == "__main__": Main().run()
方案2:手动传递实例作为第一个参数
如果一定要用类的未绑定方法,需要把实例作为第一个参数传入args:
import threading class Map(): def __init__(self): self.fig = load('HugeFig') def second(self, arg1, arg2): self.fig.show() class Main(): def run(self): map_instance = Map() # 目标为类的未绑定方法时,args第一个参数必须是Map实例,后续为方法参数 thread = threading.Thread(target=Map.second, args=(map_instance, arg1, arg2)) thread.start() if __name__ == "__main__": Main().run()
额外注意事项
- 确保
arg1和arg2在Main.run()方法中是已定义的变量,否则会报未定义错误。 - Plotly的
fig对象并非线程安全,若多个线程同时修改同一个fig可能引发异常。建议每个线程基于原始fig创建副本(如fig_copy = self.fig.copy()),再对副本进行范围设置和保存操作。
内容的提问来源于stack exchange,提问作者Carlos
相关产品推荐
相关产品推荐

