【问题标题】:Flask Application Circular DependenciesFlask 应用循环依赖
【发布时间】:2020-07-19 17:42:08
【问题描述】:

我正在开发一个 Flask 应用程序,但我不确定为什么会出现此错误:

  File "app.py", line 17, in <module>
    from endpoints.users.resource import UserResource
  File "{basedir}/endpoints/users/resource.py", line 4, in <module>
    from .model import User
  File "{basedir}/endpoints/users/model.py", line 1, in <module>
    from app import db
  File "{basedir}/app.py", line 17, in <module>
    from endpoints.users.resource import UserResource
ImportError: cannot import name 'UserResource' from 'endpoints.users.resource' ({basedir}/endpoints/users/resource.py)

我相信这是由于循环依赖,从查看错误开始,但我不知道为什么,因为我认为我在代码中导入内容的顺序应该可以规避这个问题:

app.py:

from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config.from_object(Config)
db = SQLAlchemy(app)

api = Api(app)
api.prefix = '/api'

from endpoints.users.resource import UserResource

api.add_resource(UserResource, '/users')
 
if __name__ == '__main__':
    app.run(host="0.0.0.0")

端点/用户/model.py:

from app import db

class User(db.Model):
    # info about the class, requires db

端点/用户/resource.py:

from flask_restful import Resource
from .model import User
from app import db

class UserResource(Resource):
    def get(self, username=None):
        # get request, requires db and User

在app.py中,由于我是在创建db之后从endpoints.users.resource导入的,那不应该绕过循环依赖吗?

此外,我可以使用flask run 运行它,但是当我尝试使用python app.py 时,它会出现上述错误。为什么这些会给出不同的结果?

【问题讨论】:

    标签: python flask model flask-restful


    【解决方案1】:

    所以在from endpoints.users.resource import UserResource 行python 尝试将from app import db 行导入app.py,这导致app 引用自身,这根本不好。

    解决 Flask 中循环导入错误的一种解决方法是使用大多数 Flask 应用程序中存在的init_app 函数。所以只需像这样创建database 文件:

    数据库.py

    from flask_sqlalchemy import SQLAlchemy
    db = SQLAlchemy()
    

    app.py

    from flask import Flask
    from flask_restful import Api
    from database import db
    from endpoints.users.resource import UserResource
    
    app = Flask(__name__)
    
    app.config.from_object(Config)
    db.init_app(app)
    
    api = Api(app)
    api.prefix = '/api'
    
    
    
    api.add_resource(UserResource, '/users')
     
    if __name__ == '__main__':
        app.run(host="0.0.0.0")
    

    端点/用户/model.py:

    from database import db
    
    class User(db.Model):
        # info about the class, requires db
    

    端点/用户/resource.py:

    from flask_restful import Resource
    from endpoints.users.model import User
    from database import db
    
    class UserResource(Resource):
        def get(self, username=None):
            # get request, requires db and User
    

    请注意,我重写了您从相关的导入,所以不要忘记添加 __init__.py 文件
    你的结构会是这样的:

    .
    ├── app.py
    └── database.py/
    └── endpoints/
            ├── __init__.py
            └── users/
                ├── __init__.py
                ├── model.py
                └── resource.py
    
    

    【讨论】:

    • 感谢您的帮助! __init__.py 文件的用途是什么?
    • @user11799 他们是为了帮助python索引模块。因此,当您启动 app.py 时,python 会递归地在每个子目录中检查这些文件,并且您只能导入模块,在哪个目录中您有 __init__.py 。好的做法是在每个子目录中都有 __init__.py 文件子目录(但不在根目录中)。文件可能为空。
    • @user11799 如果您没有这些文件,则导入的唯一方法是相对文件(就像您对from .model import User 所做的那样),但这种方法的缺点是您无法导入从父目录。在我的例子中,我们想导入比model高2级的database文件
    猜你喜欢
    • 2010-10-28
    • 2010-09-12
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多