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中的XML库4Suite Server的介绍
Apr 14 Python
Python中利用sqrt()方法进行平方根计算的教程
May 15 Python
使用Pyinstaller的最新踩坑实战记录
Nov 08 Python
python中多层嵌套列表的拆分方法
Jul 02 Python
django Serializer序列化使用方法详解
Oct 16 Python
python游戏开发之视频转彩色字符动画
Apr 26 Python
flask 实现上传图片并缩放作为头像的例子
Jan 09 Python
在tensorflow中实现去除不足一个batch的数据
Jan 20 Python
JupyterNotebook 输出窗口的显示效果调整实现
Sep 22 Python
Python用requests库爬取返回为空的解决办法
Feb 21 Python
Python使用海龟绘图实现贪吃蛇游戏
Jun 18 Python
Python3中最常用的5种线程锁实例总结
Jul 07 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 默默经典版本
2009/08/04 PHP
PHP实现AES256加密算法实例
2014/09/22 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
CodeIgniter配置之SESSION用法实例分析
2016/01/19 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
laravel实现上传图片,并且制作缩略图,按照日期存放的代码
2019/10/16 PHP
浅谈Javascript嵌套函数及闭包
2010/11/09 Javascript
JQuery优缺点分析说明
2011/04/10 Javascript
用Juery网页选项卡实现代码
2011/06/13 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
JavaScript中数组Array.sort()排序方法详解
2017/03/01 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
Express+Nodejs 下的登录拦截实现代码
2017/07/01 NodeJs
Node.js五大应用性能技巧小结(必须收藏)
2017/08/09 Javascript
vue语法自动转typescript(解放双手)
2019/09/18 Javascript
Bootstrap告警框(alert)实现弹出效果和短暂显示后上浮消失的示例代码
2020/08/27 Javascript
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
python正则表达式抓取成语网站
2013/11/20 Python
浅谈Python中range和xrange的区别
2017/12/20 Python
Python3 使用cookiejar管理cookie的方法
2018/12/28 Python
Python绘图Matplotlib之坐标轴及刻度总结
2019/06/28 Python
python下PyGame的下载与安装过程及遇到问题
2019/08/04 Python
python多线程同步之文件读写控制
2021/02/25 Python
python中的TCP(传输控制协议)用法实例分析
2019/11/15 Python
Windows 下更改 jupyterlab 默认启动位置的教程详解
2020/05/18 Python
Python enumerate() 函数如何实现索引功能
2020/06/29 Python
Python如何实现自带HTTP文件传输服务
2020/07/08 Python
css3实现动画的三种方式
2020/08/24 HTML / CSS
财务经理的岗位职责
2013/12/17 职场文书
大学社团活动策划书
2014/01/26 职场文书
演讲比赛获奖感言
2014/02/02 职场文书
积极贯彻学习两会精神总结
2014/03/17 职场文书
2014年五四青年节演讲比赛方案
2014/04/22 职场文书
JS实现数组去重的11种方法总结
2022/04/04 Javascript