python - FastAPI:全局变量与模块变量
问题描述
我希望有一个全局变量,仅限于 FastAPI 请求执行,但对多个模块是通用的。下面是一个小例子来解释这个问题:
我用一个主文件app.py和一个模块mymodule构建了一个非常简单的应用程序。对于每个测试,我使用 1 个工作人员在 uvicorn 中启动应用程序,然后打开 2 个 python 控制台来调用长短调用 requests.get("http://localhost:8000/fakelongcall", {"configtest": "long"} ), requests.get("http://localhost:8000/fakeshortcall", {"configtest": "short"})。
第一种情况:它正在工作,但全局变量 GLOBAL_VAR 不在模块中,因此其他模块无法访问(我可能错了)。
应用程序.py
import time
from fastapi import FastAPI
GLOBAL_VAR = "default"
app = FastAPI()
@app.get("/fakelongcall")
def fakelongcall(configtest: str):
cpt = 0
while cpt < 10:
print(GLOBAL_VAR)
time.sleep(1)
cpt = cpt + 1
@app.get("/fakeshortcall")
def fakeshortcall(configtest: str):
GLOBAL_VAR = configtest
print("Change done !")
输出
INFO: Started server process [34182]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
default
default
Change done !
INFO: 127.0.0.1:52250 - "GET /fakeshortcall?configtest=short HTTP/1.1" 200 OK
default
default
default
default
default
default
default
default
第二种情况:两个调用都在改变同一个变量,这不是预期的,但是该变量可以在一个很好的模块中访问。
应用程序.py
import time
from fastapi import FastAPI
import mymodule
app = FastAPI()
@app.get("/fakelongcall")
def fakelongcall(configtest: str):
cpt = 0
while cpt < 10:
print(mymodule.GLOBAL_VAR)
time.sleep(1)
cpt = cpt + 1
@app.get("/fakeshortcall")
def fakeshortcall(configtest: str):
mymodule.GLOBAL_VAR = configtest
print("Change done !")
我的模块.py
GLOBAL_VAR = "默认"
输出
INFO: Started server process [33994]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
default
default
default
Change done !
INFO: 127.0.0.1:52240 - "GET /fakeshortcall?configtest=short HTTP/1.1" 200 OK
short
short
short
short
short
short
short
为什么会这样?一名工作人员如何同时执行 2 个电话?我可以做些什么来获得不同 API 请求之间不共享的模块变量?为什么在模块中嵌入相同的代码会改变行为?
在此先感谢您的帮助。
解决方案
这是处理全局变量时的一个典型陷阱。从常见问题解答:
在 Python 中,仅在函数内部引用的变量是隐式全局的。如果一个变量在函数体内的任何地方都被赋值,除非明确声明为全局变量,否则它被假定为局部变量。
在第二种情况下,您正在访问导入模块的成员,该成员不会创建局部变量。
要修复它,请使用global
关键字:
def foo():
global GLOBAL_VAR
GLOBAL_VAR = configtest
推荐阅读
- java - 如何获取JR中的剩余线程?
- r - 解决 R 中的无约束优化问题
- sql - 你如何 Window.partitionBy 超过一个范围或条件?
- vb.net - 连接必须有效并打开
- r - 尝试下载空间多边形数据帧时,HTTP 状态为“403 Forbidden”
- c# - 如何在不安装 wkhtmltopdf 的情况下在 arm32 上将 html 转换为 pdf
- wpf - WPF:如何将 2 个文本框的 2 个文本属性传递到我的 Button 命令中
- javascript - 使用 css 和 javascript 管理显示
- vim - vim ipython 在带有 eclim 的分屏中
- identityserver4 - 长时间运行任务的访问令牌