为什么使用sys.path.append(path)而不是sys.path.insert(1,path)?

编辑:基于Ulf Rompe的评论, 重要的是你使用“1”而不是“0” ,否则你会打破sys.path 。

我一直在做python了一段时间(一年多),而且我总是困惑,为什么人们推荐你使用sys.path.append()而不是sys.path.insert() 。 让我来certificate一下。

比方说,我正在研究一个名为PyWorkbooks(安装在我的计算机上)的模块,但是我正在同时使用一个包含PyWorkbooks的不同模块(比方说PyJob)。 当我在PyJob上工作时,我在PyWorkbooks中发现错误,所以我想导入一个开发版本。

有两种方法可以同时工作(例如,我可以将PyWorkbooks项目放在PyJob中),但是有时我仍然需要使用path。 但是, 我不能简单地执行一个sys.path.append()到PyWorkbooks所在的文件夹 。 为什么? 因为python会先find我安装的PyWorkbook!

这就是为什么你必须做一个sys.path.insert(1,path_to_dev_pyworkbooks)

综上所述:

 sys.path.append(path_to_dev_pyworkbooks) import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one 

要么:

 sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0** import PyWorkbooks # imports correct file 

这在过去对我造成了一些困扰,如果我们(作为一个社区)开始推荐sys.path.insert(1, path) ,就好像你正在手动插入一个我认为是的path安全地说,这是你想要使用的path!

或者我有什么问题? 这是一个困扰我的问题,我希望它公开!

如果你有一个包/模块的多个版本,你需要使用virtualenv (强调我的):

virtualenv是创build独立Python环境的工具。

正在解决的基本问题是依赖和版本之一,以及间接的权限。 想象一下你有一个需要LibFoo版本1的应用程序,但是另一个应用程序需要版本2.你怎么能使用这两个应用程序? 如果你把所有东西都安装到/usr/lib/python2.7/site-packages (或者你的平台的标准位置),那么很容易导致无意中升级不应该升级的应用程序。

或者更一般地说,如果你想安装一个应用程序,并保持它是什么? 如果应用程序正常工作,则其库中的任何更改或这些库的版本都可能会中断应用程序。

另外,如果您不能将软件包安装到全局site-packages目录中呢? 例如,在共享主机上。

在所有这些情况下, virtualenv可以帮助你。 它会创build一个具有自己的安装目录的环境,它不会与其他虚拟环境共享库(也可能不访问全局安装的库)。

这就是为什么人们认为insert(0,是错误的 – 对于pipe理多个环境的问题,这是一个不完整的解决scheme。

如果您确实需要使用sys.path.insert,请考虑将sys.path [0]保持原样:

 sys.path.insert(1, path_to_dev_pyworkbooks) 

这可能很重要,因为第三方代码可能依赖于sys.path文档一致性:

在程序启动时初始化,这个列表中的第一个项目path [0]是包含用于调用Python解释器的脚本的目录。

你混淆了追加和前置的概念。 下面的代码是预先考虑的:

 sys.path.insert(1,'/thePathToYourFolder/') 

它将把新的信息放在你的解释器将要经历的search顺序的开始处(准确的说是第二个)。 sys.path.append()把东西放在search顺序的最后。

build议你使用像virtualenv这样的东西,而不是每次手动编写你的包目录到PYTHONPATH 。 为了设置不同的生态系统,将你的站点包和可能的python版本分开,请阅读这两个博客:

  1. python生态系统介绍

  2. 引导python虚拟环境

如果你决定走向环境隔离的道路,你一定会从virtualenvwrapper中受益: http : //www.doughellmann.com/docs/virtualenvwrapper/