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

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

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

1. 一个circular import实例

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

flask_demo\app\auth\__init__.py__init__.pyrun_server.py

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

from flask import Flask
from flask_login import LoginManagerdef create_app():app = Flask(__name__)from app.auth import auth_bpapp.register_blueprint(auth_bp)return appapp = 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 appapp.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 appFile "/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_appfrom app.auth import auth_bpFile "/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的执行顺序会变成这样:

我们以上面的例子来分件,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 LoginManagerlogin_manager = LoginManager() # 在auth模块运行之前,先声明login_managerdef create_app():app = Flask(__name__)login_manager.init_app(app)from app.auth import auth_bpapp.register_blueprint(auth_bp)return appapp = create_app()

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

python 报错 most likely due to a circular import 解决方法相关推荐

  1. python 报错 AttributeError: module ‘time‘ has no attribute ‘clock 解决方法

    源码如下: #引入所需要的时间库 import datetime import time#程序计时器,启动计时器 start = time.clock()#中间是放置需要测试运行时间的程序代码#计算启 ...

  2. import skimage报错ImportError: numpy.core.multiarray failed to import解决

    报错 ImportError: numpy.core.multiarray failed to import 解决方法 Jupyter 如果是Jupyter,shutdown内核,再重新打开文件运行. ...

  3. python中引入包的时候报错AttributeError: module ‘sys‘ has no attribute ‘setdefaultencoding‘解决方法?

    python中引入包的时候报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法? 参考文章: (1)pyth ...

  4. vue 报错 Cannot read property ‘__ob__‘ of undefined的解决方法

    vue 报错 Cannot read property '__ob__' of undefined的解决方法 参考文章: (1)vue 报错 Cannot read property '__ob__' ...

  5. php 正则报错,PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析...

    本文实例讲述了PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法.分享给大家供大家参考,具体如下: 环境错误级别:error ...

  6. 支付宝 报错 rsa_private read error : private key is NULL解决方法

    原因:  真机调试IOS支付宝功能GDB出现 rsa_private read error : private key is NULL提示 调试iOS 支付宝SDK的时候,执行demo.把 Partn ...

  7. zabbix报错cannot set resource limit: [13] Permission denied解决方法

    zabbix报错cannot set resource limit: [13] Permission denied解决方法 参考文章: (1)zabbix报错cannot set resource l ...

  8. vue报错 Uncaught (in promise) NavigationDuplicated {_name:““NavigationDuplicated“... 的解决方法

    vue报错 Uncaught (in promise) NavigationDuplicated {_name:""NavigationDuplicated"... 的解 ...

  9. mybatis项目报错:java.sql.SQLException: ORA-00911: 无效字符 解决方法

    mybatis项目报错:java.sql.SQLException: ORA-00911: 无效字符 解决方法 参考文章: (1)mybatis项目报错:java.sql.SQLException: ...

最新文章

  1. LeetCode简单题之三维形体的表面积
  2. 游戏人生(一),我的lua之旅:那些坑爹的CCBReaderLoad
  3. 搭建 LNMP 环境
  4. 一篇文章助你了解机器学习
  5. 在OpenCV中将cv::Mat绘制到MFC的视图中
  6. 抖音计算机音乐你要我,抖音你要我怎么做是什么歌 抖音你要我怎么做怎么说才能爱我歌曲介绍...
  7. Spring Data JPA 从入门到精通~SpEL表达式的支持
  8. php弹幕技术轮询,PHP+Ajax实现在线聊天长轮询
  9. ViBe(Visual Background extractor)背景建模或前景检测
  10. No valid Qt version set. Set one in Tools/Options 问题(QT)
  11. url 的正则表达式:path-to-regexp
  12. python创意实用案例-分享10个给Python小白看的实用案例,入门Python就在这里了
  13. springmvc+ueditor上传路径(个人备忘)
  14. sql生成(查询数据的存储过程)代码的存储过程
  15. 性能测试--jmeter中参数化【14】
  16. 深度卷积神经网络(一)
  17. 雷丁CAN通讯信号上位机软件
  18. 阿里总参谋长曾鸣:区块链中没有绝对的“去中心化”
  19. 伸缩式起重机的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  20. Linux-Centos7防火墙配置

热门文章

  1. 使用VScode开发ESP32,PlatformIO开发ESP32
  2. 关于stm32的数据类型
  3. 收藏起来,史上最全的 MySQL 高性能优化实战总结!
  4. 有赞11·11:全链路压测方案设计与实施详解
  5. [Android]实现类似微信的延迟加载的Fragment——LazyFragment
  6. DNS域名服务器双master+ntp时间服务器双主+keepalived企业高可用方案 附脚本
  7. php empty详解
  8. Ansible中文手册
  9. c++ map 的基本操作
  10. 修改及查看mysql数据库的字符集