推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
plko345
V2EX  ›  Python

flask 的 Working outside of application context 求助

  •  
  •   plko345 · Dec 19, 2020 · 4537 views
    This topic created in 2147 days ago, the information mentioned may be changed or developed.

    在类属性读 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 后执行, 又报了循环导入的问题, 想请教这个该怎么解决

    18 replies  •  2020-12-21 13:54:30 +08:00
    SjwNo1
    SjwNo1
    Dec 19, 2020
    1
    with current_app. app_context()
    sentanl869
    sentanl869
    Dec 19, 2020
    2
    既然你使用 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
    SjwNo1
    Dec 19, 2020
    3
    @SjwNo1 错误理解楼主的意思了,加载类的时候无法获取上下文信息,除非你 create_app (猜测的~
    SjwNo1
    SjwNo1
    Dec 19, 2020
    4
    或者可以把类写在 app.py 下 (逃~
    Lemeng
    Lemeng
    Dec 19, 2020
    5
    学习一下新姿势
    plko345
    plko345
    OP
    Dec 19, 2020 via Android
    6
    @SjwNo1 不能,那就乱了
    plko345
    plko345
    OP
    Dec 19, 2020 via Android
    7
    @SjwNo1 我确实有个 creat_app,,尝试过也不成功,试了不少方式,也查了一些东西,但就是不行
    plko345
    plko345
    OP
    Dec 19, 2020 via Android
    8
    @sentanl869 谢谢解答,如果不行的话只能实例化了
    johnsona
    johnsona
    Dec 19, 2020 via iPhone
    9
    大白话意思就是,你的那断代码不是一个请求来了调用的,而是项目一起来那段代码就执行了
    sentanl869
    sentanl869
    Dec 20, 2020❤️1
    10
    我脑子下午也是秀逗了,其实根本不是上下文的问题,

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

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

    总共有三个文件:app.py ,run.py ,example.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
    sentanl869
    Dec 20, 2020
    11
    我又想了下,想我楼上这么 import app 进行初始化类,运行的时候可不就得循环引用了......

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

    而是放在别的地方,比如建个新的独立文件 config.py 什么的
    no1xsyzy
    no1xsyzy
    Dec 20, 2020❤️1
    12
    我问下,你 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
    plko345
    OP
    Dec 20, 2020
    13
    @sentanl869 额, 我就是放到 config.py 里的, 然后 app 初始化的时候使用里面的配置
    johnsona
    johnsona
    Dec 20, 2020
    14
    @plko345 初始化的时候,你把 app 对象传给你你那个类,或者你手动 push 一下吧
    snBDX1b0jJM4ogKd
    snBDX1b0jJM4ogKd
    Dec 21, 2020 via Android
    15
    确保 from flask import current_app 这句运行之前先 create app
    SjwNo1
    SjwNo1
    Dec 21, 2020
    16
    @cs010 这估计是不行的,因为脱离了应用上下文
    no1xsyzy
    no1xsyzy
    Dec 21, 2020
    17
    @cs010 不存在的,你看官网的样例都没有这么做,甚至在 create_app 里面执行 import xxx
    这句导入就会执行到子模块的 from flask import current_app
    sentanl869
    sentanl869
    Dec 21, 2020
    18
    @plko345 那就试试直接 from config import EX_URL 吧,反正也只是想完成类初始化不是(逃~
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2004 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 16:27 · PVG 00:27 · LAX 08:27 · JFK 11:27
    ♥ Do have faith in what you're doing.