首页 > 编程语言 >python 报错 most likely due to a circular import 解决方法

python 报错 most likely due to a circular import 解决方法

时间:2022-08-27 17:59:29浏览次数:51  
标签:python app py due auth init 报错 import

原因各个python文件,互相引用,造成的 循环引用问题。

解决方法:把需要引用的独立成一个文件,让其单向引用

使用python写一个稍微大一点的工程时,经常会遇到循环import,即cicular import的问题。这篇文章会以flask里遇到的一个问题为原型,介绍一下
cicular import产生的原因,以及python中使用import文件时,到底python在做什么。

1. 一个circular import实例

之前遇到一个circular import的问题,项目文件结构大概如下:

flask_demo\
  app\
    auth\
      __init__.py
    __init__.py
  run_server.py

app目录下__init__.py文件内容如下:

from flask import Flask
from flask_login import LoginManager
 
def create_app():
    app = Flask(__name__)
 
    from app.auth import auth_bp
    app.register_blueprint(auth_bp)
 
    return app
    
app = create_app()
login_manager = LoginManager(app)

app/auth目录下__init__.py文件内容如下:

from flask import Blueprint
from app import login_manager
 
# 注册蓝图
auth_bp = Blueprint('auth_bp', __name__)

最后运行run_server.py文件:

from app import app
 
app.run()

这个时候flask web应用并不会成功启动起来,而是会报下面的错误:

Traceback (most recent call last):
  File "/Users/caoxin/work/python_project/flask_demo/run_server.py", line 10, in <module>
    from app import app
  File "/Users/caoxin/work/python_project/flask_demo/app/__init__.py", line 24, in <module>
    app = create_app()
  File "/Users/caoxin/work/python_project/flask_demo/app/__init__.py", line 17, in create_app
    from app.auth import auth_bp
  File "/Users/caoxin/work/python_project/flask_demo/app/auth/__init__.py", line 11, in <module>
    from app import login_manager
ImportError: cannot import name 'login_manager' from 'app' (/Users/caoxin/work/python_project/flask_demo/app/__init__.py)

这是一个典型的cicular import问题,要解决这个问题,需要能够很好的理解,在python中使用import时,代码到底是如何运行的。

2. import执行过程

当我们import一个文件时,python会首先去查找这个文件之前是否被import过,如果这个文件之前有被import过,就不会重新再import一次。
所以如果A模块代码里import了B模块,并且B模块里又import了A模块,python的执行顺序会变成这样:

开始执行模块A
当A执行到import B的地方,则停止执行A模块后面的代码,转而开始执行B模块的代码
当B模块从头执行到import A的地方时,python此时并不会回过头去接着执行A剩余的代码,而且将A模块在中断前已经初始化的属性全加载到B模块中

我们以上面的例子来分析,

app/init.py中create_app()方法中的from auth import auth_bp会中断app/init.py的执行,转而去执行auth/init.py。
需要注意的是,此时app/init.py里的app和login_manager两个属性都是声明的。
而auth/init.py又想从app模块里导入login_manager这个属性。
很显然,这里就会报错。

要解决这个问题,我们就需要重新设计代码结构,保证在auth/init.py在执行到from app import login_manager时,app模块中已经定义了login_manager。如下:

from flask import Flask
from flask_login import LoginManager
 
login_manager = LoginManager() # 在auth模块运行之前,先声明login_manager
 
def create_app():
    app = Flask(__name__)
    login_manager.init_app(app)
 
    from app.auth import auth_bp
    app.register_blueprint(auth_bp)
 
    return app
 
app = create_app()

所以理解了python在import时的工作原理,这种circular import的问题便很好分析和解决了。

标签:python,app,py,due,auth,init,报错,import
From: https://www.cnblogs.com/andy0816/p/16631031.html

相关文章

  • 小记 【django git python】
    迁移此处生成的迁移文件包含了所有的表结构(已创建和未创建的表)pythonmanage.pymakemigrationsapp_namepythonmanage.pymigrate--fake-initial--fake-initial的......
  • Python中read()、readlines()、readline()
    一、介绍读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系......
  • Python自学教程8-数据类型有哪些注意事项
    不知不觉,python自学教程已经更新到第八篇了,再有几篇,基本的语法就介绍完了。今天来总结一下数据类型有哪些需要注意的地方。元组注意事项元组是另一种经常使用到的数据类......
  • 学习:python进阶 chain
    python官方提供了itertools的包,方便操作迭代器,这个包提供了chain函数,兼顾内存效率和写法优雅       ......
  • Python教程:文件和读写的详细教程
    文件操作的模式文件操作的模式如下表:1.open打开文件使用open打开文件后一定要记得调用文件对象的close()方法。比如可以用try/finally语句来确保最后能关闭文......
  • 学习:python进阶 for循环本质
    思考:python中有while循环为很么还有for循环? 结论:while循环可以做循环遍历操作,但是远远不如for循环简结实用。while循环适合做条件循环,for循环适合做迭代器循环。......
  • 学习:python进阶 (一)
    python解释器多版本共存1.下载需要的版本安装包2.增加环境变量,把优先用的python放到第一个修改python.exe可执行文件,在终端输入对应名称可以指定需要运行的python版本......
  • Python中itertools
    一、介绍itertools是python的迭代器,itertools提供的工具相当高效且节省内存使用这些工具,可创建自己定制的迭代器用于高效率循环1.count(初值=0,步长=1):1fromitertool......
  • Python - Requests(文件上传)
    文件上传(Form表单方式)1,单文件上传(1)下面是最简单的文件上传代码,运行后将logo.png这个文件上传到服务器:importrequests......Python-第三方HTTP库Requests使......
  • Python环境安装
    一、下载地址https://www.python.org/downloads/二、安装软件这里介绍Windows系统下python环境安装InstallNow:为默认安装(不建议),不然会把环境自动安装到个人目录里,找......