Flask应用重复请求时全局变量aggregate出现未定义错误
问题分析与解决
问题重现
你的代码结构如下(已补充明显笔误部分):
api.py
import trainer from flask import Flask, jsonify app = Flask(__name__) @app.route('/start', methods=['POST']) def apifunc(id): result = trainer.consume(id) return jsonify(result) if __name__ == '__main__': LISTEN_PORT = 5000 app.run(debug=True, port=LISTEN_PORT, threaded=True, use_reloader=False)
trainer.py
from utilities import function1 def consume(id): agg1 = 10 # 原代码未定义agg1,此处为示例补充 value = function1(agg1) # ... some codes... return value
utilities.py
aggregate = 30 def function1(agg1): global aggregate # ... some codes... print(aggregate)
首次请求/start接口可正常读取aggregate,第二次请求直接报错:
ERROR:api:500 Internal Server Error: name 'aggregate' is not defined
重启应用后恢复正常。
核心原因
问题出在多线程共享模块全局变量上:
你开启了Flask的threaded=True模式,所有请求线程会共享utilities.py模块中的aggregate变量。如果第一次请求的function1逻辑里(即你写的... some codes...部分),执行了del aggregate语句,或者因动态修改模块命名空间等操作把这个变量从模块中移除,后续线程再访问时自然会触发NameError。
解决办法
1. 检查并修复变量删除操作
先排查utilities.py的function1代码,移除任何del aggregate的语句,确保变量始终存在。如果需要修改变量值,用线程锁保证操作的线程安全性:
# utilities.py import threading aggregate = 30 _agg_lock = threading.Lock() def function1(agg1): global aggregate with _agg_lock: # 在这里执行对aggregate的修改或读取操作 # ... some codes... print(aggregate)
2. 改用线程局部存储
如果不需要跨线程共享aggregate的值,用threading.local()为每个线程分配独立的变量副本,避免线程间干扰:
# utilities.py import threading _thread_local = threading.local() def _init_aggregate(): if not hasattr(_thread_local, 'aggregate'): _thread_local.aggregate = 30 def function1(agg1): _init_aggregate() # 用_thread_local.aggregate替代原来的全局变量 # ... some codes... print(_thread_local.aggregate)
3. 彻底抛弃全局变量
重构代码,把aggregate封装成类属性或者作为参数传递,从根源上避免全局变量带来的问题:
# utilities.py class Aggregator: def __init__(self): self.aggregate = 30 def process(self, agg1): # ... some codes... print(self.aggregate) return self.aggregate # trainer.py from utilities import Aggregator def consume(id): aggregator = Aggregator() value = aggregator.process(agg1) # ... some codes... return value
内容的提问来源于stack exchange,提问作者hanzgs
相关产品推荐
相关产品推荐

