多线程中是否存在类似Flask @before_request的前置执行钩子方法?
多线程场景下实现类似Flask @before_request的方案
首先明确:Python标准库的threading模块没有内置对应@before_request的线程钩子,但可以通过自定义封装轻松实现你要的子线程自动继承主线程属性的需求,不需要在每个业务函数里手动写赋值逻辑。
方案1:自定义Thread子类(推荐,侵入性最低)
通过重写start方法,在线程启动、执行目标函数之前统一执行属性继承逻辑,后续只要替换线程创建的类即可,完全不用修改业务代码:
import threading class AutoInheritThread(threading.Thread): # 配置需要自动继承的属性列表,可按需扩展 INHERIT_ATTRS = ["id"] def start(self): # 此处就是你要的类似before_request的预处理逻辑,在线程执行前运行 main_thread = threading.main_thread() for attr in self.INHERIT_ATTRS: if attr in main_thread.__dict__: self.__dict__[attr] = main_thread.__dict__[attr] super().start() # 业务函数完全不需要改动 def say_id(): print(threading.current_thread().__dict__.get("id")) # 主线程赋值 threading.current_thread().__dict__["id"] = "id001" # 仅需要把原来的threading.Thread替换为自定义类即可 t1 = AutoInheritThread(target=say_id) t2 = AutoInheritThread(target=say_id) t1.start() t2.start()
运行后两个子线程都会自动输出id001,不需要在say_id里写赋值逻辑。
方案2:装饰器实现(适合少量业务函数场景)
如果不想修改线程创建逻辑,可以用装饰器包裹业务函数,在函数执行前自动完成属性继承:
import threading from functools import wraps def inherit_main_attr(func): @wraps(func) def wrapper(*args, **kwargs): # 函数执行前的预处理逻辑 current_thread = threading.current_thread() main_thread = threading.main_thread() current_thread.__dict__["id"] = main_thread.__dict__.get("id", "") return func(*args, **kwargs) return wrapper # 给业务函数加装饰器即可 @inherit_main_attr def say_id(): print(threading.current_thread().__dict__.get("id")) threading.current_thread().__dict__["id"] = "id001" t1 = threading.Thread(target=say_id) t2 = threading.Thread(target=say_id) t1.start() t2.start()
扩展说明
如果你的需求是子线程继承创建它的父线程的属性(而非固定继承主线程),只需要在自定义Thread类的__init__方法里保存创建时的父线程属性即可,不需要修改其他逻辑。
内容的提问来源于stack exchange,提问作者Andy Su
相关产品推荐
相关产品推荐

