我正在Flask的一个项目上工作,我在循环导入方面遇到了麻烦。
我的应用程序结构如下所示:
.
├── api
│ ├── __init__.py
│ ├── schema.py
│ └── sender.py
├── app.py
├── config.py
├── README.md
├── run.sh
├── static
│ ├── css
│ │ ├── base.css
│ │ ├── index.css
│ │ └── model.css
│ └── index.html
├── templates
│ ├── base.html
│ ├── model.html
│ ├── schema_add.html
│ ├── schema.html
│ └── table.html
└── views
├── auth.py
├── error_handler.py
├── __init__.py
├── model.py
├── schema.py
└── table.py
源代码可在this
上找到Here's a trace of error:
Traceback (most recent call last):
File "./../anton_temp/app.py", line 3, in <module>
from views import *
File
"/home/shubham1172/Documents/Anton/anton_temp/views/__init__.py", line
16, in <module>
from .auth import *
File "/home/shubham1172/Documents/Anton/anton_temp/views/auth.py",
line 4, in <module>
from app import setConnection, getConnection, closeConnection
File "/home/shubham1172/Documents/Anton/anton_temp/app.py", line 4,
in <module>
from api import *
File "/home/shubham1172/Documents/Anton/anton_temp/api/__init__.py",
line 13, in <module>
from .schema import *
File "/home/shubham1172/Documents/Anton/anton_temp/api/schema.py",
line 5, in <module>
from app import getConnection
ImportError: cannot import name 'getConnection'
问题是,我必须在我的应用中包含我的蓝图(views和api)。 这些蓝图的 init 文件还包括py文件,而py文件又必须包含应用程序中的一些功能。
我在某处读取了将这些函数包含在外部文件中,比如说extension.py,然后从蓝图中调用它,但我在app中的函数包含对其app对象的'app'的引用。
我该如何解决这个问题?
修改
正如所指出的,我将不得不重构我的代码。 This显示了同一问题的示例,并给出了解决方案。但是,我的扩展中的功能需要调用应用程序的配置,即
A.py
import B
from C import dependency
B.py
from C import dependency
C.py
def dependency():
#Use A.config here <----------
pass
有什么方法可以解决这个问题吗?
修改
我通过重构代码解决了这个问题。 我发现app.config可以通过一个简单的函数调用导出到另一个文件。
C.py
obj = None
def setObj(object):
obj = object
def dependency():
#use obj now
pass
现在可以从A.py!调用setObj(obj)
答案 0 :(得分:0)
尝试避免此问题的一种方法是捕获所有循环导入例外:
>>> try:
>>> from mylib import myclass
>>> except:
>>> pass
>>> try:
>>> from mylib2 import myclass2
>>> except:
>>> pass
另一种解决方案,我也不喜欢,在您进行操作时会导入包装。因此,您应该在需要它的函数中进行导入:
>>> def func1():
>>> from mylib import myclass
>>> c = myclass()
>>> ....
>>>
>>> def func2():
>>> from mylib2 import myclass2
>>> ...
另一种可能的方法是在创建app对象后导入所有蓝图的依赖关系。这意味着您可以安全地导入对象&#34; app&#34;因为您延迟了导入依赖项。
在你的main.py(或主文件)中:
>>> from flask import Flask
>>>
>>> app = Flask()
>>>
>>> from . import views # safe to import "app" from views.py now!
>>>
>>> a = 3 # this generates circular dependency error from views.py. it hasn't been creted yet!!
在views.py中:
>>> from .main import app # safe to import "app".
>>>
>>> app.route("/")
>>> def hello_world():
>>> ...
正如您所知,当views.py为&#34; app&#34;调用main.py时对象,它已经被创建了。
但是,最好的解决方案是重新设计您的应用。换句话说,如果您在应用中发现了这个问题,那么很明显,您没有设计它并且需要不同的文件系统架构(甚至是不同的架构)。
您还可以参考以下链接中提供的工厂设计模式:
http://flask.pocoo.org/docs/0.12/patterns/appfactories/
就个人而言,我使用工厂,到目前为止我还没有遇到任何问题。
答案 1 :(得分:0)
应用配置导入问题可由烧瓶config dictionary处理。
在模块C.py
中,您可以使用随书current_app object访问应用程序配置。
如果A.py
是您的主应用文件:
# A.py
from flask import Flask
app = Flask(__name__
app.config['MY_CONFIG_KEY'] = 'something'
然后您可以在C.py
中访问应用的配置,如下所示:
# C.py
from flask import current_app
def dependency():
v = current_app.config['MY_CONFIG_KEY']
需要注意的一件重要事情是,解决循环依赖关系的方法是使用应用程序工厂和蓝图。