什么设置 sys.path 与 Python,什么时候?

Posted

技术标签:

【中文标题】什么设置 sys.path 与 Python,什么时候?【英文标题】:What sets up sys.path with Python, and when? 【发布时间】:2011-05-15 08:43:47 【问题描述】:

当我跑步时

import sys 
print sys.path

在我的 Mac(Mac OS X 10.6.5、Python 2.6.1)上,我得到以下结果。

/Library/Python/2.6/site-packages/ply-3.3-py2.6.egg ... /Library/Python/2.6/site-packages/ipython-0.10.1-py2.6.egg /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python26.zip /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6 /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages /System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-old /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload /Library/Python/2.6/site-packages /System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC /System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/wx-2.8-mac-unicode

它们分为 5 类。

/Library/Python/2.6/site-packages/*.egg /Library/Python/2.6/site-packages Frameworks/Python.framework/Versions/2.6/lib/python2.6 Frameworks/Python.framework/Versions/2.6/Extras/lib/python 来自 PYTHONPATH 环境变量的路径。

我可以使用代码添加更多路径

sys.path.insert(0, MORE_PATH)
哪些例程设置了这些路径,何时设置? 有些路径是用python源码内置的吗? 是否可以忽略使用“sys.path.insert”插入的路径?我对此很好奇,与 mod_wsgi 一样,我发现使用“sys.path.insert”找不到路径。我问了another post 这个问题。

添加

根据 Michael 的回答,我查看了 site.py,得到了以下代码。

def addsitepackages(known_paths):
    """Add site-packages (and possibly site-python) to sys.path"""
    sitedirs = []
    seen = []

    for prefix in PREFIXES:
        if not prefix or prefix in seen:
            continue
        seen.append(prefix)

        if sys.platform in ('os2emx', 'riscos'):
            sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
        elif sys.platform == 'darwin' and prefix == sys.prefix:
            sitedirs.append(os.path.join("/Library/Python", sys.version[:3], "site-packages"))

我还认为应该将包含 site.py 的目录名称(我的 Mac 是 /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6)内置到 Python 源代码中。

【问题讨论】:

部分回复Python's sys.path value? 如果您仍然想弄清楚您之前的问题 - 您的问题很可能在于启动文件,而不是与网站导入有关。对于一个包来说,删除他们不知道的新路径是非常糟糕的做法。 为什么seen 不是一个集合? :P 我找到的同一个问题的最佳答案可以是found here,这是另一个SO问题答案的链接。 【参考方案1】:

来自学习 Python

sys.path 是模块搜索路径。 Python 在程序中对其进行配置 启动,自动合并 顶层文件的主目录 (或一个空字符串来指定 当前工作目录),任何 PYTHONPATH 目录,内容 您拥有的任何 .pth 文件路径 创建和标准库 目录。结果是一个列表 Python 的目录名字符串 搜索新文件的每次导入。

【讨论】:

【参考方案2】:

大部分内容是在 Python 的 site.py 中设置的,它会在启动解释器时自动导入(除非您使用 -S 选项启动它)。在初始化期间,解释器本身中设置的路径很少(您可以通过使用 -S 启动 python 来找出哪些路径)。

此外,一些框架(我认为像 Django)会在启动时修改 sys.path 以满足他们的要求。

site 模块有一个很好的documentation,一个注释source code,如果你通过python -m site 运行它,它会打印出一些信息。

【讨论】:

显然在 Debian 及其衍生版本中,/usr/local/lib/python<version>/dist-packages/usr/lib,share/python<version>/dist-packages 中的目录会自动添加到路径中(根据 Ubuntu 14.04 中的 /usr/lib/python2.7/site.py)。【参考方案3】:

路径包含以下部分:

包含系统库的操作系统路径 python 开始的当前目录 环境变量$PYTHONPATH 您可以在运行时添加路径。

路径不会被忽略。但是,可能找不到它们,这不会引发错误。 sys.path 也应该只添加,而不是从中减去。 Django 不会删除路径。

【讨论】:

【参考方案4】:

site.py 确实是答案。我想删除默认安装在我的 mac 上的旧 Python 的任何依赖项。这很好用,因为每次启动 python 解释器时都会调用“site.py”。

对于 Mac,我在 /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/site.py 的 main() 末尾手动添加了以下行:

    sys.path =  filter (lambda a: not a.startswith('/System'), sys.path)

【讨论】:

请记住site.py可以在运行Python时使用命令行-S选项阻止运行。从docs - 禁用模块site 的导入以及它所需要的sys.path 的站点相关操作。【参考方案5】:

添加到已接受的答案,并解决那些说模块不应从 sys.path 中删除条目的 cmets:

这大体上是正确的,但的情况下,您可能希望通过删除条目来修改sys.path。例如 - 这是特定于 Mac 的; *nix/Windows 推论可能存在 - 如果您创建自定义 Python.framework 以包含在您自己的项目中,您可能希望忽略指向系统 Python.framework 的默认 sys.path 条目。

你有几个选择:

    破解site.py,如@damirv 所示,或

    将您自己的sitecustomize 模块(或包)添加到实现相同最终结果的自定义框架中。如site.py cmets 所示(无论如何,对于 2.7.6):

    在这些路径操作之后,尝试导入一个模块 命名为sitecustomize,可以执行任意附加 特定于站点的自定义。如果此导入失败并显示 ImportError 异常,它被静默忽略。

【讨论】:

【参考方案6】:

另请注意:如果设置了PYTHONHOME env var,标准库将从该路径而不是默认路径加载,如documented。

这不是问题的直接答案,而是我刚刚发现导致加载错误的标准库的原因,我的搜索一直引导我到这里。

【讨论】:

PYTHONHOME 在 mod_wsgi 的情况下并不真正适用,因为 Apache 不会从用户环境启动,并且它从系统单元脚本启动的 root 用户不会设置它。 @GrahamDumpleton 也许,但问题的标题可能会在更一般的情况下引导其他人。我只是希望这些信息对某人有所帮助。【参考方案7】:

您正在使用系统 python /usr/bin/python

sys.path 在 python 启动时从系统文件中设置。

不要触摸这些文件,尤其是 site.py,因为这可能会干扰系统。

但是,您可以在 python 中更改 sys.path,特别是在启动时:

在 ~/.bashrc 或 ~/.zshrc 中:

export PYTHONSTARTUP=~/.pythonrc

在~/.pythonrc:

将您的更改写入 sys.path。

这些更改仅适用于交互式 shell。

为了对系统造成很小的黑客攻击,请安装您自己的和更新的 python 版本。

【讨论】:

你怎么知道“你正在使用系统python /usr/bin/python。”?

以上是关于什么设置 sys.path 与 Python,什么时候?的主要内容,如果未能解决你的问题,请参考以下文章

python中os.path 与sys.path

python 面试题

python -m xx.py和python xx.py的区别

Python:系统变量路径已更改,与 sys.path 中的值不匹配

sys模块

sys模块