Python 加载模块时使用sys.path.insert(0,path)和sys.path(append)的效果
我最近遇到了一个python ImportError问题,在本地计算机上运行时发现了该模块,但在CI服务器上找不到。我通过将脚本中的Python 加载模块时使用sys.path.insert(0,path)和sys.path(append)的效果,python,pythonpath,Python,Pythonpath,我最近遇到了一个python ImportError问题,在本地计算机上运行时发现了该模块,但在CI服务器上找不到。我通过将脚本中的sys.path.append(path)替换为sys.path.insert(0,path)解决了这个问题,其中path是字符串模块的位置 既然这是我的模块,而不是已安装的软件包(),为什么路径顺序可以解决这个问题呢?因为python从sys.path列表中的第一个目录开始按顺序检查目录,直到找到它要查找的.py文件 理想情况下,当前目录或脚本的目录是列表中的第一
sys.path.append(path)
替换为sys.path.insert(0,path)
解决了这个问题,其中path
是字符串模块的位置
既然这是我的模块,而不是已安装的软件包(),为什么路径顺序可以解决这个问题呢?因为python从
sys.path
列表中的第一个目录开始按顺序检查目录,直到找到它要查找的.py
文件
理想情况下,当前目录或脚本的目录是列表中的第一个元素,除非像您那样修改它。从-
当程序启动时初始化时,此列表的第一项路径[0]是包含用于调用Python解释器的脚本的目录。如果脚本目录不可用(例如,如果以交互方式调用解释器或从标准输入读取脚本),则路径[0]是空字符串,它将指示Python首先搜索当前目录中的模块。请注意,脚本目录是在作为PYTHONPATH结果插入的条目之前插入的
因此,最有可能的情况是,您在当前目录(运行脚本的位置)中有一个.py
文件,该文件与您试图从中导入的模块同名
另外,关于导入错误,有一点需要注意-
ImportError:没有名为main的模块
-这并不意味着main.py
被覆盖,不,如果被覆盖,我们在尝试读取时不会遇到问题。它上面的某个模块被一个.py
或其他文件覆盖
范例-
我的目录结构看起来像-
- test
- shared
- __init__.py
- phtest.py
- testmain.py
现在从testmain.py
,我从共享导入phtest调用,它工作正常
现在让我们假设我在test
directory`中引入了一个shared.py,例如-
- test
- shared
- __init__.py
- phtest.py
- testmain.py
- shared.py
现在,当我从testmain.py
尝试从共享导入phtest执行时,我将得到错误-
ImportError: cannot import name 'phtest'
正如您在上面看到的,导致问题的文件是shared.py
,而不是phtest.py
,我是Python的初学者,我发现Anand的答案非常好,但对我来说非常复杂,因此我尝试重新表述:
1) insert
和append
方法不是特定于sys.path
的,与其他语言一样,它们将项目添加到列表或数组中:
*附加(项目)
将项目添加到列表末尾,
*插入(n,项)
在列表的第n个位置插入项
(0
在开头,1
在第一个元素之后,等等…)
2) 正如Anand所说,python按照路径的顺序搜索路径的每个目录中的导入文件,因此:
*如果没有文件名冲突,则路径顺序没有影响,
*如果您查看路径中已定义的函数,并使用append
添加路径,则不会获得函数,而是获得预定义的函数
但是我认为最好使用append
和notinsert
来避免Python的标准行为过载,并为您的文件和方法使用不含糊的名称。我的模块是something.main,我尝试将其改为something.engine,以查看这是否是问题所在,但我仍然存在导入错误,这让我觉得这不是模块名称/文件冲突。回溯的最后一行是“ImportError:没有名为main的模块”您有回溯吗,也许这有帮助这是circleci输出,恐怕有点有限-我在将“main”重命名为“engine”时遇到了类似的错误。可能是重复的