无法从 Python 中部分初始化的模块“connection”导入名称“mydb”

Mar*_*res 29 python importerror

Python 3.8 错误

ImportError: cannot import name 'mydb' from partially initialized module 'connection' 
(most likely due to a circular import) (C:\U
sers\Mark04\Documents\Python tutorial\databasing\connection.py)
Run Code Online (Sandbox Code Playgroud)

当我尝试执行子模块 select.py

import bcrypt;
from connection import mydb
Run Code Online (Sandbox Code Playgroud)

那有一个导入的模块 connection.py

import mysql.connector
mydb = "Success";
Run Code Online (Sandbox Code Playgroud)

我不知道是什么问题。当我从我的模块 connection.py 中删除 import mysql.connector 时没有出现错误,但它没有解决我的问题。

> python -m select
Run Code Online (Sandbox Code Playgroud)

Jay*_*lik 34

要回答上述问题,我们需要了解循环依赖的问题。

为了理解循环依赖,我想布局一个简单的例子,在你面前。

我认为每个应用程序都需要具有以下几个基本块:

+----------------+-------------------------------------------------------------------------------------------+
|    Filename    |                                        Description                                        |
+----------------+-------------------------------------------------------------------------------------------+
| app.py         | Creates the app and starts the server.                                                    |
| models.py      | Define what the entity will look like (e.g, UserModel has username, email, password etc.) |
| controllers.py | Fetches Data from database, generates HTML and sends the response to the user browser.    |
+----------------+-------------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

我们的简单示例也将包含三个文件

project/
    - app.py ( Creates and starts the server)
    - models.py ( Class to model a user)
    - controllers.py ( We will fetch data from database, and return html to user.)
Run Code Online (Sandbox Code Playgroud)

app.py 文件的内容如下所示:

+----------------+-------------------------------------------------------------------------------------------+
|    Filename    |                                        Description                                        |
+----------------+-------------------------------------------------------------------------------------------+
| app.py         | Creates the app and starts the server.                                                    |
| models.py      | Define what the entity will look like (e.g, UserModel has username, email, password etc.) |
| controllers.py | Fetches Data from database, generates HTML and sends the response to the user browser.    |
+----------------+-------------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

models.py 文件的内容如下所示:

project/
    - app.py ( Creates and starts the server)
    - models.py ( Class to model a user)
    - controllers.py ( We will fetch data from database, and return html to user.)
Run Code Online (Sandbox Code Playgroud)

controller.py 文件的内容如下所示:

# =============
#     app.py
# =============

# Define the application
app = Flask()

# Define the Database
db = SQLAlchemy(app)

# Register the Controller
from .controllers import auth_controller
app.register_blueprint(auth_controller)
Run Code Online (Sandbox Code Playgroud)

我想现在,我已经绘制了我们的应用程序的图表,现在让我们继续了解该应用程序的工作原理。

  1. 该应用程序从 app.py
  2. appapp.py文件中的变量在内存中创建。
  3. dbapp.py在内存中创建的内部变量。
  4. 现在,auth要从controllers.py文件导入,我们切换到 ```controllers.py`` 文件
  5. 我们Blueprint从烧瓶进口。
  6. 要导入User,我们切换到models.py文件。
  7. 现在,在models.py我们导入的文件中db(我们能够导入它,因为它是在步骤 3 中创建的)
  8. 和程序继续等等......

上述序列中最重要的导入步骤是step 7,因为它会导致我们的应用程序中的循环依赖问题,在一瞬间。

现在我们将尝试更改app.py文件以引入循环依赖的问题。

现在,作为开发人员,我们可能认为我们所有的导入都应该在文件的顶部,这不是让您的代码更简洁吗?是的当然!它确实使代码更干净。

# =============
#     models.py
# =============

from .app import db

# We will not focus on implementation
class User(db.Model):
    pass

Run Code Online (Sandbox Code Playgroud)

现在,我们的应用程序中存在循环依赖问题。让我来告诉你怎么做?

  1. 我们的应用程序从app.py文件开始
  2. 首先,我们需要auth_controllercontrollers.py文件导入
  3. 让我们访问该controllers.py文件并对其进行处理。
  4. 我们从烧瓶中导入蓝图
  5. 让我们切换到models.py要导入的文件User
  6. models.py文件内部,我们导入dbfrom app (但 db 尚不存在。)

现在,我想你明白了,刚才看到的问题是循环依赖的一个例子。同样的问题导致ImportError您的情况。

解决方案是检查import statements它们并将它们放在正确的位置。有时,我们使用代码格式化程序,它重构了顶部的所有导入语句。这可能会给您带来问题。

我希望这可以回答你的问题!


小智 23

您可以通过不导入文件顶部的冲突导入之一来消除此错误。如果您只想在某个地方使用导入的内容,则可以在函数中进行导入。

def foo():
    from x import y
Run Code Online (Sandbox Code Playgroud)


Ben*_*Ben 22

进口的顺序很重要:

例子:

# A.py
# empty file
Run Code Online (Sandbox Code Playgroud)
# B.py
import A
Run Code Online (Sandbox Code Playgroud)
# file1.py
import A # A gets imported before B can import A
import B # B tries to re-import A but A is already imported
Run Code Online (Sandbox Code Playgroud)

将顺序更改为:

# file1.py
import A # A gets imported before B can import A
import B # B tries to re-import A but A is already imported
Run Code Online (Sandbox Code Playgroud)

  • 这是为我做的,问题不完全是循环引用,而是在导入该模块并且调用第一个模块的引用之前,模块没有被导入到模块中 (3认同)

小智 7

当您尝试循环导入时会出现此错误。确保您没有在目录中创建与您尝试导入的模块同名的任何文件。