PYTHONPATH与sys.path

gae*_*fan 79 python python-import pythonpath sys.path

另一位开发人员和我不同意是否应该使用PYTHONPATH或sys.path来允许Python在用户(例如,开发)目录中查找Python包.

我们有一个具有典型目录结构的Python项目:

Project
    setup.py
    package
        __init__.py
        lib.py
        script.py
Run Code Online (Sandbox Code Playgroud)

在script.py中,我们需要这样做import package.lib.当软件包安装在site-packages中时,script.py可以找到package.lib.

但是,当从用户目录工作时,还需要做其他事情.我的解决方案是将我的PYTHONPATH设置为包含"〜/ Project".另一位开发人员希望将这行代码放在script.py的开头:

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Run Code Online (Sandbox Code Playgroud)

这样Python就可以找到本地副本了package.lib.

我认为这是一个坏主意,因为这行只对开发人员或从本地副本运行的人有用,但我不能说明为什么这是一个坏主意.

我们应该使用PYTOHNPATH,sys.path,还是要么?

Ned*_*der 42

如果修改路径的唯一原因是开发人员在其工作树中工作,那么您应该使用安装工具为您设置环境.virtualenv非常受欢迎,如果您使用的是setuptools,您只需运行setup.py develop以在当前的Python安装中半安装工作树.

  • 您可以对此提供更多说明吗?即使您站在conda / virtualenv环境中,这如何将顶级目录放在python路径上? (2认同)

bob*_*nce 36

我讨厌PYTHONPATH.我发现在每个用户的基础上设置(特别是对于守护程序用户)并且跟踪项目文件夹移动时会很脆弱和烦人.我宁愿sys.path在独立项目的调用脚本中设置它.

然而sys.path.append,不是这样做的方式.您可以轻松获取重复项,而不会对.pth文件进行排序.更好(更可读的): site.addsitedir.

并且script.py通常不会是更合适的地方,因为它你想要在路径上提供的包.图书馆模块当然不应该触动sys.path自己.相反,你通常在软件包之外有一个用于实例化和运行应用程序的hashbanged-script,而在这个简单的包装器脚本中你可以放置部署细节,如sys.path-frobbing.

  • `site.addsitedir`的问题在于它在`sys.path`上做了一个`append`,这意味着一个已安装的包将优先于开发中的本地包(并且可能会随之拉动).`sys.path.insert(0 ...`需要克服它. (14认同)
  • @EliBendersky:应该是`sys.path.insert(1`.http://stackoverflow.com/q/10095037/125507 (4认同)

Pet*_*ter 11

由于前面提到的原因,黑客攻击PYTHONPATH也不是一个好主意。sys.path为了将当前项目链接到 site-packages 文件夹中,实际上有一种比 更好的方法python setup.py develop,如下所述

pip install --editable path/to/project

如果您的项目根文件夹中还没有 setup.py,那么从这个开始就足够了:

from setuptools import setup
setup('project')
Run Code Online (Sandbox Code Playgroud)


sat*_*esh 10

一般来说,我会考虑设置一个环境变量(如PYTHONPATH)是一个不好的做法.虽然这可能适用于一次性调试,但使用它作为
常规练习可能不是一个好主意.


其他人报告代码库中的问题时,环境变量的使用会导致"它适用于我"这样的情况.也可以在测试环境中进行相同的练习,导致测试对于特定开发人员运行良好但在某些人启动测试时可能会失败.


shy*_*ent 5

我认为,在这种情况下使用 PYTHONPATH 是一件更好的事情,主要是因为它不会引入(有问题的)不必要的代码。

毕竟,如果您考虑一下,您的用户不需要那个sys.path东西,因为您的包将被安装到站点包中,因为您将使用打包系统。

如果用户选择从“本地副本”运行,正如您所说,那么我观察到,通常的做法是声明,如果在站点包之外使用,则需要手动将包添加到 PYTHONPATH .


unu*_*tbu 5

除了已经提到的许多其他原因之外,您还可以指出硬编码

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

之所以会变脆,是因为它假定script.py的位置-仅当script.py位于Project / package中时才起作用。如果用户决定将script.py(几乎)移动/复制/符号链接(几乎)在其他任何地方,它将中断。