Swift51.com
麦子学院 头像
麦子学院  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.pyb.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 出现两次,因此可以判断是这个文件引起的循环导入。
  要解决这个问题,可以把模块看成一种资源,对所有要引入的模块进行编号,再按静态资源排序法顺次导入,就可以避免循环导入。
来源: 黑斑马笔记