我最近遇到了python ImportError的问题,在我的本地计算机上运行但在CI服务器上找不到该模块。我通过在sys.path.append(path)
脚本中交换sys.path.insert(0, path)
来解决此问题,其中path
是字符串模块位置。
由于这是我的模块而不是已安装的软件包(related question),为什么路径顺序可以解决此问题?
答案 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)insert
和append
方法并非特定于sys.path
,而在其他语言中,它们会将项目添加到列表或数组中,并且:
* append(item)
将item
添加到列表的末尾,
* insert(n, item)
将item
插入列表中的第n个位置(开头为0
,第一个元素后为1
等等。)
2)正如Anand所说,python按路径的顺序搜索路径的每个目录中的导入文件,因此:
*如果没有文件名冲突,路径的顺序没有影响,
*如果您照看路径中已定义的函数并使用append
添加路径,则不会获得预定义的函数。
但我认为最好使用append
而不是insert
来重载Python的标准行为,并为文件和方法使用非模糊名称。