flask 的 Working outside of application context 求助

2020-12-19 12:20:41 +08:00
 plko345

在类属性读 flask 的配置报错

from flask import current_app

class Foo(object):
    URL = current_app.config['EX_URL']
    ...
  File "/path/to/example.py", line 20, in Foo
    URL = current_app.config['EX_URL']
  File "/path/to/miniconda/envs/example/lib/python3.8/site-packages/werkzeug/local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/path/to/miniconda/envs/example/lib/python3.8/site-packages/werkzeug/local.py", line 306, in _get_current_object
    return self.__local()
  File "/path/to/miniconda/envs/example/lib/python3.8/site-packages/flask/globals.py", line 52, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.

提示是让执行 app.app_context() , 我尝试导入 from start import app 后执行, 又报了循环导入的问题, 想请教这个该怎么解决

3177 次点击
所在节点    Python
18 条回复
SjwNo1
2020-12-19 13:59:48 +08:00
with current_app. app_context()
sentanl869
2020-12-19 14:25:01 +08:00
既然你使用 current_app 而 flask 报 outside of application context,

说明你的 flask app 根本没有在运行,所以也就没有应用上下文。

如果只是想完成类的初始化,就想办法 import 你的 app,

```python
with app.app_context():
class Foo(object):
...
```

或者你可以不做上面的改动:

```python
class Foo(object):
URL = ''

__init__(self):
self.URL = current_app.config['EX_URL']
```

在生成实例的的时候再给 URL 属性赋值。
SjwNo1
2020-12-19 14:27:55 +08:00
@SjwNo1 错误理解楼主的意思了,加载类的时候无法获取上下文信息,除非你 create_app (猜测的~
SjwNo1
2020-12-19 14:30:41 +08:00
或者可以把类写在 app.py 下 (逃~
Lemeng
2020-12-19 14:51:03 +08:00
学习一下新姿势
plko345
2020-12-19 19:21:31 +08:00
@SjwNo1 不能,那就乱了
plko345
2020-12-19 19:23:53 +08:00
@SjwNo1 我确实有个 creat_app,,尝试过也不成功,试了不少方式,也查了一些东西,但就是不行
plko345
2020-12-19 19:25:49 +08:00
@sentanl869 谢谢解答,如果不行的话只能实例化了
johnsona
2020-12-19 21:56:10 +08:00
大白话意思就是,你的那断代码不是一个请求来了调用的,而是项目一起来那段代码就执行了
sentanl869
2020-12-20 00:16:46 +08:00
我脑子下午也是秀逗了,其实根本不是上下文的问题,

你初始化类使用 app.config 的内容根本不需要上下文。

既然你有 create_app 那就好办了,我写了个 demo 试了一下,是可以成功初始化类的:

总共有三个文件:app.pyrun.pyexample.py

app.py:

from flask import Flask


def create_app():
____app = Flask(__name__)
____app.config['EX_URL'] = 'www.example.com'
____return app

- - - - -

run.py:

from app import create_app


app = create_app()

- - - - -

example.py:

from run import app


class Foo:
____URL = app.config['EX_URL']

- - - - -

测试结果:

>>> from example improt Foo
>>> Foo.URL
>>> 'www.example.com'

所以根本问题是,你这种类初始化完全不该用 current_app,毕竟类初始化的时候 app 没有在运行。

而 current_app 本质是一个上下文应用的代理,没有 app 在运行自然代理不到任何东西,你被这个报错误导了。

所以其实你要解决的就是循环引用的问题。
sentanl869
2020-12-20 00:37:18 +08:00
我又想了下,想我楼上这么 import app 进行初始化类,运行的时候可不就得循环引用了......

所以,感觉,你这种初始化类要引用的数据,似乎不该放在 app.config 里,

而是放在别的地方,比如建个新的独立文件 config.py 什么的
no1xsyzy
2020-12-20 02:21:12 +08:00
我问下,你 Foo.URL 在什么情况下会被使用?

1. 如果只在实例化后使用,
1a. 写在 __init__ 里
1b. 写成 property
1c. 也可沿用 2. 里的方法。

2. 如果类可能不会被实例化,
2a. 写成 staticmethod get_url()
2b. metaclass 里写成 property (不推荐,“你多半用不上 metaclass”)
2c.
from werkzeug.local import LocalProxy
URL = LocalProxy(lambda: current_app.config['EX_URL'])
plko345
2020-12-20 20:37:33 +08:00
@sentanl869 额, 我就是放到 config.py 里的, 然后 app 初始化的时候使用里面的配置
johnsona
2020-12-20 21:36:41 +08:00
@plko345 初始化的时候,你把 app 对象传给你你那个类,或者你手动 push 一下吧
cs010
2020-12-21 09:35:12 +08:00
确保 from flask import current_app 这句运行之前先 create app
SjwNo1
2020-12-21 09:59:55 +08:00
@cs010 这估计是不行的,因为脱离了应用上下文
no1xsyzy
2020-12-21 11:23:47 +08:00
@cs010 不存在的,你看官网的样例都没有这么做,甚至在 create_app 里面执行 import xxx
这句导入就会执行到子模块的 from flask import current_app
sentanl869
2020-12-21 13:54:30 +08:00
@plko345 那就试试直接 from config import EX_URL 吧,反正也只是想完成类初始化不是(逃~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/737014

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX