由于特定的 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
。我觉得这很奇怪,原因有二:
addsitedir
在lib/python2.7/site-packages
上运行了两次。- 这本身并没有那么糟糕(没有什么可以添加到 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.py
将site-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 manually 的 imp.find_module()
来加载原始 site.py
和 imp.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/