麦子学院 2017-08-30 19:54
Python学习之导入错误详解
回复:0 查看:2847
当遇到无法导入某个python
模块时,可能会是没有安装某个模块,也有可能是某模块在加载过程中失败,也有可能是陷入了循环导入的问题。本文将为大家详细分析python
导入错误相关内容,一起来看看吧,希望对大家
学习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 sysprint(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
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
出现两次,因此可以判断是这个文件引起的循环导入。
要解决这个问题,可以把模块看成一种资源,对所有要引入的模块进行编号,再按静态资源排序法顺次导入,就可以避免循环导入。
来源:
黑斑马笔记