Python导入模块时遇到的错误分析


Posted in Python onAugust 30, 2017

当遇到无法导入某个python模块时,可能会是没有安装某个模块,也有可能是某模块在加载过程中失败,也有可能是陷入了循环导入的问题。本文详细解释了这个问题。

1. 模块未安装或者路径不对

ImportError: No mudule named myModule

有两种可能,一是该模块没有安装,一般可以用

pip install %module_name%

来解决。注意有时候模块安装包名并不等于要导入的模块名。这种情况下可以通过pip search | list命令来尝试找到正确的包。

另一种情况就是包虽然安装了,但当前运行的程序加载的路径有错。python运行时将从以下位置尝试加载python modules:

* 当前目录

* 环境变量$PYTHONPATH所指示的值,这是一个由“:”分隔的字符串,各个子字符串都是文件系统的一个路径。

* 标准库目录,如dist-site-packages下的模块。

* 在.pth文件中指定的路径,如果存在.pth文件的话。

可以使用以下方式来查看python运行时的包含路径:

import sys
print(sys.path)

在运行出错的脚本装头部加上这一段代码,然后在控制台中查看打印出来的python类库路径,检查安装包是否已包含在上述路径中。

***可以通过下面的方式将未包含在路径中的模块临时包含进来:***

sys.path.append("path/to/module")

另外,还可以在shell窗口中查看当前的python包含路径:

echo $PYTHONPATH

2. 无法导入已存在的模块

如果要导入的模块包含了native代码,并且native代码加载(初始化)失败时,就会导致这种错误。使用ssl, gevent等涉及native的模块时,如果对应的native程序并未安装,则会出现这样的错误。

另一种错误情况是,使用相对路径导入时,父模块还未导入成功。见下面的代码:

main.py
mypackage/
  __init__.py
mymodule.py
myothermodule.py

mymodule.py如下所示:

#!/usr/bin/env python3

# Exported function
def as_int(a):
  return int(a)

# Test function for module 
def _test():
  assert as_int('1') == 1

if __name__ == '__main__':
  _test()

以及myothermodule代码如下所示:

#!/usr/bin/env python3

from .mymodule import as_int

# Exported function
def add(a, b):
  return as_int(a) + as_int(b)

# Test function for module 
def _test():
  assert add('1', '1') == 2

if __name__ == '__main__':
  _test()

如果执行mypackage/myothermodule,则会报以下错误:

Traceback (most recent call last):
 File "myothermodule.py", line 3, in <module>
   from .mymodule import as_int
SystemError: Parent module '' not loaded, cannot perform relative import
[这篇文章](#Relative imports in Python 3)给出了更详细的解答。

3. 循环导入

这种错误称之为"circular (or cyclic) imports"。是python独有的一种导入错误,在象java这样的语言中就不存在。

假设有如下两个文件,a.py和b.py:

#a.py
print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"
print b.x

以及:

#b.py
print "b in"
import a
print "b out"
x = 3

执行python a.py,将得到以下结果:

$ python a.py
a in          
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
 File "a.py", line 4, in <module>
  import b
 File "/home/shlomme/tmp/x/b.py", line 2, in <module>
  import a
File "/home/shlomme/tmp/x/a.py", line 7, in <module>
  print b.x
AttributeError: 'module' object has no attribute 'x'

出现这种情况的原因是产生了循环导入。循环导入,以及在导入过程中python进行了加锁操作,最终导致在模块b未导入完成时就引用了其中的名字。

判断导入错误是否是因为循环导入引起的,主要看堆栈中是否出现两次重复的导入。比如上述堆栈中a.py出现两次,因此可以判断是这个文件引起的循环导入。

要解决这个问题,可以把模块看成一种资源,对所有要引入的模块进行编号,再按静态资源排序法顺次导入,就可以避免循环导入。

Python 相关文章推荐
介绍Python的Django框架中的QuerySets
Apr 20 Python
Python数据分析之双色球基于线性回归算法预测下期中奖结果示例
Feb 08 Python
Python SVM(支持向量机)实现方法完整示例
Jun 19 Python
如何通过雪花算法用Python实现一个简单的发号器
Jul 03 Python
python自定义函数实现最大值的输出方法
Jul 09 Python
如何通过python的fabric包完成代码上传部署
Jul 29 Python
python Dijkstra算法实现最短路径问题的方法
Sep 19 Python
python 中不同包 类 方法 之间的调用详解
Mar 09 Python
使用opencv识别图像红色区域,并输出红色区域中心点坐标
Jun 02 Python
什么是python的必选参数
Jun 21 Python
Python判断变量是否是None写法代码实例
Oct 09 Python
Django显示可视化图表的实践
May 10 Python
简单学习Python多进程Multiprocessing
Aug 29 #Python
Python简单实现自动删除目录下空文件夹的方法
Aug 29 #Python
Python实现文件内容批量追加的方法示例
Aug 29 #Python
Python实现解析Bit Torrent种子文件内容的方法
Aug 29 #Python
Python 3.x读写csv文件中数字的方法示例
Aug 29 #Python
在python3环境下的Django中使用MySQL数据库的实例
Aug 29 #Python
Python网络爬虫与信息提取(实例讲解)
Aug 29 #Python
You might like
php数组函数序列之asort() - 对数组的元素值进行升序排序,保持索引关系
2011/11/02 PHP
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
可以保证单词完整性的PHP英文字符串截取代码分享
2014/07/15 PHP
php实现的日历程序
2015/06/18 PHP
php实现统计目录文件大小的函数
2015/12/25 PHP
Yii2使用$this-&gt;context获取当前的Module、Controller(控制器)、Action等
2017/03/29 PHP
PHP实现redis限制单ip、单用户的访问次数功能示例
2018/06/16 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
2013/04/02 Javascript
一个网页标题title的闪动提示效果实现思路
2014/03/22 Javascript
使用jQuery判断浏览器滚动条位置的方法
2016/05/30 Javascript
sencha ext js 6 快速入门(必看)
2016/06/01 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
Layui数据表格跳转到指定页的实现方法
2019/09/05 Javascript
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
2020/06/19 Javascript
[16:04]DOTA2海涛带你玩炸弹 9月5日更新内容详解
2014/09/05 DOTA
Python备份Mysql脚本
2008/08/11 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
2016/06/07 Python
Python3 XML 获取雅虎天气的实现方法
2018/02/01 Python
Python for循环生成列表的实例
2018/06/15 Python
python RSA加密的示例
2020/12/09 Python
HTMl5的存储方式sessionStorage和localStorage详解
2014/03/18 HTML / CSS
快速创建 HTML5 Canvas 电信网络拓扑图的示例代码
2018/03/21 HTML / CSS
澳大利亚首屈一指的鞋类品牌:Tony Bianco
2018/03/13 全球购物
Casetify官网:自制专属手机壳、iPad护壳和Apple Watch手表带
2018/05/09 全球购物
介绍一下#error预处理
2015/09/25 面试题
学年自我鉴定
2014/01/16 职场文书
策划创业计划书
2014/02/06 职场文书
岗位明星事迹材料
2014/05/18 职场文书
村级四风对照检查材料
2014/08/24 职场文书
婚前协议书标准版
2014/10/19 职场文书
2015年小班保育员工作总结
2015/05/27 职场文书
2015年教师节新闻稿
2015/07/17 职场文书
Python使用sql语句对mysql数据库多条件模糊查询的思路详解
2021/04/12 Python
python用海龟绘图写贪吃蛇游戏
2021/06/18 Python