Python 对导入的 Flask 模块进行类型提示
Python type hinting on imported Flask modules
我发现 Flask 的自动完成功能有些欠缺。这是因为在内部,特定于上下文的对象(例如 current_app
、request
和 logger
实际上是 LocalProxy
对象。因此 PyCharm 合理地不知道如何处理这种类型。
一种解决方案是对导入的模块应用类型提示。除了你不能那样做!从 Python 3.7 开始,似乎没有这样的语法来促进这一点。
因此,下一个显而易见的解决方案是制作每个上下文特定模块的本地副本,并明确设置类型,如下所示:
from logging import Logger
from flask import Flask, Request, Blueprint, request, current_app as app
app: Flask = app
logger: Logger = app.logger
request: Request = request
这一直有效,直到您实际尝试启动服务器,在这种情况下,应用程序会因为 RuntimeError: Working outside of application context.
而崩溃
事实证明,我们实际上可以将相关类型提示封装在应用程序上下文中的 class 或其他范围内。
@foo_blueprint.route('/foo', methods=['GET'])
def foo(cls):
_app: Flask = app
_logger: Logger = app.logger
_request: Request = request
# ...
这可行,但在任何可以想象的意义上都非常笨拙。
在 Flask 的应用程序上下文中获取正确的类型提示是否有合理的解决方案?
你试过了吗?我知道它至少在从其他模块导入普通变量时有效。
# in module_a.py
my_str = 23
# in module_b.py
from module_a import my_str
my_str: str
# The IDE should now suggest string methods when trying to access
# properties of `my_str`
2022 年更新
开始于 Flask version 2.0.0, type hints are now built-in to the library. (See pull request #3973)
2.0.0 之前的 Flask 版本
对于旧版本的 Flask,一种解决方法是使用类型转换,如下所示:
from typing import cast
from flask import request
from flask import Request
from flask import Response
@app.route('/')
def index() -> Response:
# Can't use `assert isinstance(request, Request)`, since `request` is `LocalProxy` object.
global request
request = cast(Request, request)
token = request.headers.get('authorization')
...
return 'API is working', 200
我发现 Flask 的自动完成功能有些欠缺。这是因为在内部,特定于上下文的对象(例如 current_app
、request
和 logger
实际上是 LocalProxy
对象。因此 PyCharm 合理地不知道如何处理这种类型。
一种解决方案是对导入的模块应用类型提示。除了你不能那样做!从 Python 3.7 开始,似乎没有这样的语法来促进这一点。
因此,下一个显而易见的解决方案是制作每个上下文特定模块的本地副本,并明确设置类型,如下所示:
from logging import Logger
from flask import Flask, Request, Blueprint, request, current_app as app
app: Flask = app
logger: Logger = app.logger
request: Request = request
这一直有效,直到您实际尝试启动服务器,在这种情况下,应用程序会因为 RuntimeError: Working outside of application context.
事实证明,我们实际上可以将相关类型提示封装在应用程序上下文中的 class 或其他范围内。
@foo_blueprint.route('/foo', methods=['GET'])
def foo(cls):
_app: Flask = app
_logger: Logger = app.logger
_request: Request = request
# ...
这可行,但在任何可以想象的意义上都非常笨拙。
在 Flask 的应用程序上下文中获取正确的类型提示是否有合理的解决方案?
你试过了吗?我知道它至少在从其他模块导入普通变量时有效。
# in module_a.py
my_str = 23
# in module_b.py
from module_a import my_str
my_str: str
# The IDE should now suggest string methods when trying to access
# properties of `my_str`
2022 年更新
开始于 Flask version 2.0.0, type hints are now built-in to the library. (See pull request #3973)
2.0.0 之前的 Flask 版本
对于旧版本的 Flask,一种解决方法是使用类型转换,如下所示:
from typing import cast
from flask import request
from flask import Request
from flask import Response
@app.route('/')
def index() -> Response:
# Can't use `assert isinstance(request, Request)`, since `request` is `LocalProxy` object.
global request
request = cast(Request, request)
token = request.headers.get('authorization')
...
return 'API is working', 200