Flask 2.2.2:current_app._get_current_object()的合规替代写法咨询
解决Flask中current_app._get_current_object()的PyCharm警告问题
PyCharm弹出的警告是因为_get_current_object()方法以下划线开头,被识别为类的受保护成员,但在Flask中,这个方法是官方推荐用于从current_app代理对象中获取实际应用实例的方式——因为current_app是一个代理,在多线程场景下(比如你的异步邮件发送线程),直接传递代理会失效,必须获取背后真实的应用实例。
更合适的写法(两种方案)
方案1:保留原有逻辑,添加PyCharm警告抑制注释
这是最简单的方式,既保留官方推荐的写法,又消除警告:
def send_email(to, subject, template, **kwargs): # noinspection PyProtectedMember app = current_app._get_current_object() msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject, sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to]) msg.body = render_template(template + '.txt', **kwargs) msg.html = render_template(template + '.html', **kwargs) thr = Thread(target=send_async_email, args=[app, msg]) thr.start() return thr
添加# noinspection PyProtectedMember注释后,PyCharm会忽略该行的受保护成员访问警告。
方案2:通过应用上下文栈获取实例(不依赖受保护方法)
如果你想完全避免使用受保护方法,可以通过Flask内部的应用上下文栈提取实例,但此方式依赖内部模块,未来版本可能变动:
def send_email(to, subject, template, **kwargs): from flask._app_ctx_stack import top app = top.app msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject, sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to]) msg.body = render_template(template + '.txt', **kwargs) msg.html = render_template(template + '.html', **kwargs) thr = Thread(target=send_async_email, args=[app, msg]) thr.start() return thr
为什么原有写法是正确的
Flask的current_app是LocalProxy对象,它会在请求/应用上下文存在时动态指向当前Flask应用实例。但异步线程不会自动继承上下文,因此必须获取真实的应用实例传递给线程,再在线程内手动推送应用上下文(with app.app_context()),才能让mail.send()正常工作。
内容的提问来源于stack exchange,提问作者J Griffin
相关产品推荐
相关产品推荐

