加载模块时使用sys.path.insert(0,path)和sys.path(append)的效果

时间:2015-07-08 11:42:20

标签: python pythonpath

我最近遇到了python ImportError的问题,在我的本地计算机上运行但在CI服务器上找不到该模块。我通过在sys.path.append(path)脚本中交换sys.path.insert(0, path)来解决此问题,其中path是字符串模块位置。

由于这是我的模块而不是已安装的软件包(related question),为什么路径顺序可以解决此问题?

2 个答案:

答案 0 :(得分:23)

因为python从sys.path列表中的第一个目录开始按顺序检查目录,直到找到它正在寻找的.py文件。

理想情况下,当前目录或脚本目录是第一个始终是列表中的第一个元素,除非您像修改它一样修改它。来自documentation -

  

在程序启动时初始化时,此列表的第一项path [0]是包含用于调用Python解释器的脚本的目录。如果脚本目录不可用(例如,如果以交互方式调用解释器或者从标准输入读取脚本),则路径[0]为空字符串,它指示Python首先搜索当前目录中的模块。请注意,在作为PYTHONPATH结果插入的条目之前插入了脚本目录。

因此,很可能,您在当前目录(运行脚本的位置)中有一个.py文件,其名称与您尝试导入的模块的名称相同。

另外,关于ImportError的注意事项,让我们说导入错误说 - ImportError: No module named main - 这并不意味着main.py被覆盖,如果被覆盖则不会,我们不会在尝试阅读时遇到问题。它上面的一些模块被。py或其他文件覆盖。

示例 -

我的目录结构如下 -

 - test
    - shared
         - __init__.py
         - phtest.py
  - testmain.py

现在来自testmain.py,我致电from shared import phtest,它运作正常。

现在假设我在test目录中引入了shared.py,例如 -

 - test
    - shared
         - __init__.py
         - phtest.py
  - testmain.py 
  - shared.py

现在,当我尝试从from shared import phtest执行testmain.py时,我会收到错误 -

ImportError: cannot import name 'phtest'

正如您在上面所看到的,导致问题的文件是shared.py,而不是phtest.py

答案 1 :(得分:19)

我是Python的初学者,我发现Anand的答案非常好,但对我来说很复杂,所以我尝试重新制定:

1)insertappend方法并非特定于sys.path,而在其他语言中,它们会将项目添加到列表或数组中,并且:   * append(item)item添加到列表的末尾,
  * insert(n, item)item插入列表中的第n个位置(开头为0,第一个元素后为1等等。)

2)正如Anand所说,python按路径的顺序搜索路径的每个目录中的导入文件,因此:
  *如果没有文件名冲突,路径的顺序没有影响,
  *如果您照看路径中已定义的函数并使用append添加路径,则不会获得预定义的函数。

但我认为最好使用append而不是insert来重载Python的标准行为,并为文件和方法使用非模糊名称。