python:lib/site-packages/site.py 和 lib/site.py 之间的相互作用

标签 python linux python-2.7 sys.path

由于特定的 problem我设法解决了这个问题,我今天大部分时间都在弄清楚 site.py(s) 是如何工作的。有一点我不明白。

据我了解,当加载 python 时,首先运行 lib/python2.7/site-packages/site.py。它遍历 PYTHONPATH,搜索 lib/python2.7/site.py,然后导入它。这个文件有addsitedir方法,不仅给sys.path添加了一个路径,还处理了它上面的*.pth文件.此时,运行 lib/python2.7/site.py 中的 main(),并在 site-packages 上运行 addsitedir 和在用户站点包上。

奇怪的部分来了。现在我们回到 lib/python2.7/site-packages/site.py,它遍历 pythonpath 中的每个路径,并在其上运行 addsitedir。我觉得这很奇怪,原因有二:

  1. addsitedirlib/python2.7/site-packages 上运行了两次。
  2. 这本身并没有那么糟糕(没有什么可以添加到 sys.path 两次),但似乎 lib/python2.7/site.py 有一种机制允许雄心勃勃的用户通过实现 usercustomize 模块来操作 sys.path(嘿,它甚至在 docs 中)。显然,当您实现这种机制时,您希望确保用户最后进入,以便他可以控制添加到 sys.path 的所有内容。但这里不是这种情况(因为我很沮丧地发现)。很有可能,对 lib/python2.7/site-packages 的第二次调用将覆盖 usercustomize 中完成的所有操作。

我知道这很糟糕,但我向 addsitedir 添加了一个打印语句,打印它接收到的路径,这样我就可以显示发生了什么。这些是处理的路径:

/home/user/.local/lib/python2.7/site-packages #lib/python2.7/site.py
/home/user/py/lib/python2.7/site-packages     #lib/python2.7/site.py
#This is where your usercustomize runs
#Followin calls are from lib/python2.7/site-packages/site.py
/home/user/py/lib/python2.7/site-packages/numpy-1.9.0-py2.7-linux-x86_64.egg
/home/user/Develop/Python/myproject
/home/user/lmfit-0.7.2
/home/user/py/lib/python2.7/site-packages #NOTE: this runs a second time

所以我在这里问什么? :)

一个。对于为什么需要第二次调用 site-packages 的见解,我将不胜感激。

B. usercustomize 是否确实受到限制,因为我认为这是由于此实现造成的?考虑到这一点,您将如何实现从 sys.path 中删除路径(理论上)?


请求的调试输出:

:genie39:~ ;-) python2.7 -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# /home/user/py/lib/python2.7/site-packages/site.pyc matches /home/user/py/lib/python2.7/site-packages/site.py
import site # precompiled from /home/user/py/lib/python2.7/site-packages/site.pyc
# /home/user/py/lib/python2.7/os.pyc matches /home/user/py/lib/python2.7/os.py
import os # precompiled from /home/user/py/lib/python2.7/os.pyc
import errno # builtin
import posix # builtin
# /home/user/py/lib/python2.7/posixpath.pyc matches /home/user/py/lib/python2.7/posixpath.py
import posixpath # precompiled from /home/user/py/lib/python2.7/posixpath.pyc
# /home/user/py/lib/python2.7/stat.pyc matches /home/user/py/lib/python2.7/stat.py
import stat # precompiled from /home/user/py/lib/python2.7/stat.pyc
# /home/user/py/lib/python2.7/genericpath.pyc matches /home/user/py/lib/python2.7/genericpath.py
import genericpath # precompiled from /home/user/py/lib/python2.7/genericpath.pyc
# /home/user/py/lib/python2.7/warnings.pyc matches /home/user/py/lib/python2.7/warnings.py
import warnings # precompiled from /home/user/py/lib/python2.7/warnings.pyc
# /home/user/py/lib/python2.7/linecache.pyc matches /home/user/py/lib/python2.7/linecache.py
import linecache # precompiled from /home/user/py/lib/python2.7/linecache.pyc
# /home/user/py/lib/python2.7/types.pyc matches /home/user/py/lib/python2.7/types.py
import types # precompiled from /home/user/py/lib/python2.7/types.pyc
# /home/user/py/lib/python2.7/UserDict.pyc matches /home/user/py/lib/python2.7/UserDict.py
import UserDict # precompiled from /home/user/py/lib/python2.7/UserDict.pyc
# /home/user/py/lib/python2.7/_abcoll.pyc matches /home/user/py/lib/python2.7/_abcoll.py
import _abcoll # precompiled from /home/user/py/lib/python2.7/_abcoll.pyc
# /home/user/py/lib/python2.7/abc.pyc matches /home/user/py/lib/python2.7/abc.py
import abc # precompiled from /home/user/py/lib/python2.7/abc.pyc
# /home/user/py/lib/python2.7/_weakrefset.pyc matches /home/user/py/lib/python2.7/_weakrefset.py
import _weakrefset # precompiled from /home/user/py/lib/python2.7/_weakrefset.pyc
import _weakref # builtin
# /home/user/py/lib/python2.7/copy_reg.pyc matches /home/user/py/lib/python2.7/copy_reg.py
import copy_reg # precompiled from /home/user/py/lib/python2.7/copy_reg.pyc
import imp # builtin
# /home/user/py/lib/python2.7/site.pyc matches /home/user/py/lib/python2.7/site.py
import site # precompiled from /home/user/py/lib/python2.7/site.pyc
# /home/user/py/lib/python2.7/traceback.pyc matches /home/user/py/lib/python2.7/traceback.py
import traceback # precompiled from /home/user/py/lib/python2.7/traceback.pyc
# /home/user/py/lib/python2.7/sysconfig.pyc matches /home/user/py/lib/python2.7/sysconfig.py
import sysconfig # precompiled from /home/user/py/lib/python2.7/sysconfig.pyc
# /home/user/py/lib/python2.7/re.pyc matches /home/user/py/lib/python2.7/re.py
import re # precompiled from /home/user/py/lib/python2.7/re.pyc
# /home/user/py/lib/python2.7/sre_compile.pyc matches /home/user/py/lib/python2.7/sre_compile.py
import sre_compile # precompiled from /home/user/py/lib/python2.7/sre_compile.pyc
import _sre # builtin
# /home/user/py/lib/python2.7/sre_parse.pyc matches /home/user/py/lib/python2.7/sre_parse.py
import sre_parse # precompiled from /home/user/py/lib/python2.7/sre_parse.pyc
# /home/user/py/lib/python2.7/sre_constants.pyc matches /home/user/py/lib/python2.7/sre_constants.py
import sre_constants # precompiled from /home/user/py/lib/python2.7/sre_constants.pyc
# /home/user/py/lib/python2.7/_sysconfigdata.pyc matches /home/user/py/lib/python2.7/_sysconfigdata.py
import _sysconfigdata # precompiled from /home/user/py/lib/python2.7/_sysconfigdata.pyc
# zipimport: found 604 names in /home/user/py/lib/python2.7/site-packages/pytz-2014.7-py2.7.egg
# zipimport: found 20 names in /home/user/py/lib/python2.7/site-packages/hashlib-20081119-py2.7-linux-x86_64.egg
# zipimport: found 40 names in /home/user/py/lib/python2.7/site-packages/pysqlite-2.6.3-py2.7-linux-x86_64.egg
# zipimport: found 7 names in /home/user/py/lib/python2.7/site-packages/mock-1.0.1-py2.7.egg
import encodings # directory /home/user/py/lib/python2.7/encodings
# /home/user/py/lib/python2.7/encodings/__init__.pyc matches /home/user/py/lib/python2.7/encodings/__init__.py
import encodings # precompiled from /home/user/py/lib/python2.7/encodings/__init__.pyc
# /home/user/py/lib/python2.7/codecs.pyc matches /home/user/py/lib/python2.7/codecs.py
import codecs # precompiled from /home/user/py/lib/python2.7/codecs.pyc
import _codecs # builtin
# /home/user/py/lib/python2.7/encodings/aliases.pyc matches /home/user/py/lib/python2.7/encodings/aliases.py
import encodings.aliases # precompiled from /home/user/py/lib/python2.7/encodings/aliases.pyc
# /home/user/py/lib/python2.7/encodings/utf_8.pyc matches /home/user/py/lib/python2.7/encodings/utf_8.py
import encodings.utf_8 # precompiled from /home/user/py/lib/python2.7/encodings/utf_8.pyc
Python 2.7.8 (default, Sep  7 2014, 12:14:33) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
dlopen("/home/user/py/lib/python2.7/site-packages/readline-6.2.4.1-py2.7-linux-x86_64.egg/readline.so", 2);
import readline # dynamically loaded from /home/user/py/lib/python2.7/site-packages/readline-6.2.4.1-py2.7-linux-x86_64.egg/readline.so
>>> 

python -vv 的输出是 here

最佳答案

lib/python2.7/site-packages/site.py 文件未正常加载。这是因为 lib/python2.7/site.py 的工作是将 site-packages 路径添加到 sys.path 开始与,并且 site-packages 中的 site.py 根本不可见。如果您在 site-packages 中有一个 site.py 那么这是一个错误,那里应该没有这样的文件。

没有 is 的未打补丁的 Python 会发生什么:

  • Python 以有限的 sys.path 启动。 site-packages 不属于此列表,除非您设置包含它的 PYTHONPATH 变量。
  • Python 导入 site.py,它将导入 sys.path 中第一个列出的那个。
  • lib/python2.7/site.py 找到并加载
  • site.pysite-packages 添加到 sys.path

就是这样,不再加载 site.py 模块。即使您尝试过,它也会找到已经导入的模块; sys.modules['site'] 存在并保存从 lib/python2.7/site.py 加载的对象。

但是,您的安装安装了较旧的 setuptools,它包含一个 special version of site.py ,如果不存在,则 easy_install 命令 will install into site-packages。它将通过显式扫描原始 sys.path 并忽略任何 PYTHONPATH 提供的路径和使用 loading the original site.py module manuallyimp.find_module() 来加载原始 site.pyimp.load_module() 低级函数,从而绕过正常的模块缓存。

它的目的是改变 sys.path 命令,给 PYTHONPATH 列出的 .pth 文件更高的优先级,见 original commit adding the patch :

Note: this version includes a hacked 'site.py' to support processing .pth files in directories that come before site-packages on sys.path.

补丁已从最近的 setuptools 版本中完全删除,as early as 2006 in the original setuptools

因此,要么您的 Linux 发行版已设置为将 lib/python2.7/site-packages 添加到您的 PYTHONPATH,要么您的 shell 已经为您设置了此设置,或者您的 Python 已被修补以包含它,并且您的 site-packages 中有旧的 setuptools“补丁”。

删除该文件是完全安全的。

关于python:lib/site-packages/site.py 和 lib/site.py 之间的相互作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25715039/

相关文章:

Python:如何从FASTA文件中的滑动窗口打印长度为n的序列?

python - 如何在Python(Jinja2)中单击“导出”按钮下载文件?

python - 如何使用 boto3 获取 aws 中存在的实例和卷以及负载均衡器的总数?

python - python中的导入锁是什么?

python - Django - 以形式访问request.session

linux - 如何在 64 位主机上以 32 位模式构建 UML(用户模式 ​​linux)

linux - 在 Perl 中查找两个等长字符串之间差异的快速方法

python - 如何在 Python 3 中获取列表中的列表编号?

linux - 如何在linux(Centos 7)中配置vnc服务器?

python - 如果为真 : destruct Class