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标准库之多进程(multiprocessing包)介绍
Nov 25 Python
Python正则表达式如何进行字符串替换实例
Dec 28 Python
详谈在flask中使用jsonify和json.dumps的区别
Mar 26 Python
Tensorflow加载预训练模型和保存模型的实例
Jul 27 Python
pygame游戏之旅 添加icon和bgm音效的方法
Nov 21 Python
Python 脚本拉取 Docker 镜像问题
Nov 10 Python
Python 元组拆包示例(Tuple Unpacking)
Dec 24 Python
python模拟斗地主发牌
Apr 22 Python
Python 将 QQ 好友头像生成祝福语的实现代码
May 03 Python
Python selenium爬取微博数据代码实例
May 22 Python
keras .h5转移动端的.tflite文件实现方式
May 25 Python
详解使用Python写一个向数据库填充数据的小工具(推荐)
Sep 11 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
教你如何把一篇文章按要求分段
2006/10/09 PHP
php经典算法集锦
2015/11/14 PHP
PHP下SSL加密解密、验证、签名方法(很简单)
2020/06/28 PHP
统一接口:为FireFox添加IE的方法和属性的js代码
2007/03/25 Javascript
传智播客学习之java 反射
2009/11/22 Javascript
Jquery中获取iframe的代码
2011/01/11 Javascript
使用POST方式弹出窗口的两种方法示例介绍
2014/01/29 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
基于js实现二级下拉联动
2016/12/17 Javascript
vue.js在标签属性中插入变量参数的方法
2018/03/06 Javascript
vue项目base64字符串转图片的实现代码
2018/07/13 Javascript
node+express框架中连接使用mysql(经验总结)
2018/11/10 Javascript
JS函数进阶之prototy用法实例分析
2020/01/15 Javascript
JavaScript 如何计算文本的行数的实现
2020/09/14 Javascript
Javascript Symbol原理及使用方法解析
2020/10/22 Javascript
[00:55]深扒TI7聊天轮盘语音出处3
2017/05/11 DOTA
Python的迭代器和生成器
2015/07/29 Python
在Python中使用AOP实现Redis缓存示例
2017/07/11 Python
Python Web程序部署到Ubuntu服务器上的方法
2018/02/22 Python
python 读取.csv文件数据到数组(矩阵)的实例讲解
2018/06/14 Python
Python判断字符串是否xx开始或结尾的示例
2019/08/08 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
TensorFLow 变量命名空间实例
2020/02/11 Python
Django 多对多字段的更新和插入数据实例
2020/03/31 Python
HTML5拖拽文件到浏览器并实现文件上传下载功能代码
2013/06/06 HTML / CSS
中国电视购物:快乐购
2017/02/04 全球购物
Chain Reaction Cycles俄罗斯:世界上最大的在线自行车商店
2019/08/27 全球购物
服务员岗位职责
2014/01/29 职场文书
英文求职信写作小建议
2014/02/16 职场文书
工作会议简报
2015/07/20 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
《哪吒之魔童降世》观后感:世上哪有随随便便的成功
2019/11/08 职场文书
python数据可视化JupyterLab实用扩展程序Mito
2021/11/20 Python
JavaScript流程控制(循环)
2021/12/06 Javascript
前端框架ECharts dataset对数据可视化的高级管理
2022/12/24 Javascript