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

cannot import name 'mydb' from partially initialized module 'connection' in Python

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)

当我试图执行子模块时select.py

import bcrypt;
from connection import mydb

有导入的模块connection.py

import mysql.connector
mydb = "Success";

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

> python -m select

错误说是"most likely due to a circular import"。 检查以确保在您导入的文件中您没有导入您显示的文件。如果你是这样的话,就会形成一个进口圈子。 例如,我的文件是 file.py,我正在导入 file2.py: 导入文件 > 导入文件 2 > 导入文件 > 导入文件 2 > 导入文件... 确保没有发生这种情况。我遇到了和你一样的问题,这个问题已经解决了。

我不知道根本原因,但如果你回滚到 Python 3.7

它会工作得很好

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

导入顺序很重要:

示例:

# A.py
# empty file
# B.py
import A
# 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

将顺序更改为:

# file1.py
import B
import A

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

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

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

+----------------+-------------------------------------------------------------------------------------------+
|    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.    |
+----------------+-------------------------------------------------------------------------------------------+

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

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.)

app.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)

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

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

from .app import db

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

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

# =============
#     controllers.py
# =============
from flask import Blueprint
from .models import User


# Create the auth app
auth = Blueprint('auth', __name__)

# Define the Rotues
@auth.route('/login')
def login():
    return "I will fetch some data and allow the user to login"

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

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

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

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

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

# ============================
#       Refactored app.py file
# ============================
from .controllers import auth_controller

# ......
# Rest of the file is same, we only shifted this import at the top

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

  1. 我们的应用程序从 app.py 文件开始
  2. 首先,我们需要从 controllers.py 文件中导入 auth_controller
  3. 让我们访问 controllers.py 文件,并处理它。
  4. 我们从烧瓶中导入蓝图
  5. 让我们切换到 models.py 文件导入 User
  6. models.py文件中,我们从app导入db(但是数据库还不存在。)

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

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

希望这可以回答您的问题!

我降低了导入,而不是将所有导入放在顶部。

db = SQLAlchemy(app)
migrate = Migrate(app, db)
from models import User

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

def foo():
    from x import y