python:lib/site-packages/site.py和lib/site.py之间的相互作用 [英] python: Interplay between lib/site-packages/site.py and lib/site.py

查看:227
本文介绍了python:lib/site-packages/site.py和lib/site.py之间的相互作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我解决了特定的问题,我今天大部分时间都在研究site.py的工作方式.有一点我不明白.

Due to a specific problem which I managed to solve, I spent most of today figuring out how site.py(s) work. There is a point which I don't understand.

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

As far as I understand, when python is loaded, first lib/python2.7/site-packages/site.py is run. It goes over PYTHONPATH, searches for lib/python2.7/site.py, and imports it. This file has the addsitedir method, that not only adds a path to sys.path, but also processes *.pth files which exists on it. At this point, main() from lib/python2.7/site.py is ran, and addsitedir is ran on site-packages and on user-site-packages.

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

Now comes the weird part. Now we go back to lib/python2.7/site-packages/site.py, which goes over each path in pythonpath, and runs addsitedir on it. I find this weird for two reasons:

  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中完成的所有操作.
  1. addsitedir is ran on lib/python2.7/site-packages twice.
  2. This is not so bad in itself (nothing can be added to sys.path twice), but it seems that lib/python2.7/site.py has a mechanism for allowing the ambitious user to manipulate sys.path by implementing a usercustomize module (hey, it's even in the docs). Obviously, when you implement such a mechanism, you want to make sure the user gets in last, so he can have control over everything added to sys.path. But this is not the case here (as I was frustrated to find out). Most likely, the second call to lib/python2.7/site-packages will override everything done in usercustomize.

我知道这很糟糕,但是我在addsitedir中添加了一条打印语句,打印了接收到的路径,因此我可以显示发生了什么.这些是处理的路径:

I know it's terrible, but I added a print statement to addsitedir, printing the path it receives, so I could show what's going on. These are the paths processed:

/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

那我在这里问什么? :)

So what am I asking here? :)

A.对于需要为何第二次调用网站程序包的见解,我深表感谢.

A. I'd appreciate insights as to why the second call to site-packages is needed.

B.我相信usercustomize是否确实受此实施的限制?考虑到这一点,您将如何从理论上从sys.path中实现删除路径?

B. Is usercustomize indeed limited as I believe it is due to this implementation? Considering this, how would you implement something removing paths from sys.path (theoretically)?

请求的调试输出:

: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的输出是此处

推荐答案

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

The lib/python2.7/site-packages/site.py file is not normally loaded. That's because it is lib/python2.7/site.py's job to add the site-packages paths to sys.path to begin with, and the site.py in site-packages is simply not visible. If you have a site.py in site-packages then that is an error, there should be no such file there.

在没有修补程序的Python中发生的事情是:

What happens in an unpatched Python without is:

  • Python以有限的sys.path开始.除非您设置一个PYTHONPATH始终包含它的变量,否则site-packages不属于该列表.
  • Python导入site.py,它将导入在sys.path上首先列出的代码.
  • 找到
  • lib/python2.7/site.py并加载
  • site.pysite-packages添加到sys.path
  • Python starts, with a limited sys.path. site-packages is not part of this list, unless you set a PYTHONPATH variable that includes it anyway.
  • Python imports site.py, it'll import the one listed first on sys.path.
  • lib/python2.7/site.py is found and loaded
  • site.py adds site-packages to sys.path

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

That's it, no further site.py modules are loaded. Even if you tried, it'd find the module that was already imported; sys.modules['site'] exists and holds objects loaded from lib/python2.7/site.py.

但是,您的安装中安装了较旧的setuptools,并且其中包含将安装到site-packages 中(如果尚不存在).通过显式扫描原始sys.path并忽略任何PYTHONPATH提供的路径并 imp.load_module() 低级功能,因此绕过了常规模块缓存.

Your installation, however, has an older setuptools installed, and it includes a special version of site.py, which the easy_install command will install into site-packages if not yet present. It'll load the original site.py by explicitly scanning the original sys.path with any PYTHONPATH-supplied paths ignored and loading the original site.py module manually using the imp.find_module() and imp.load_module() low-level functions, thus bypassing the normal module cache.

其意图是更改sys.path的顺序以赋予PYTHONPATH列出的.pth文件更高的优先级,请参见

Its intent was to alter the sys.path order to give PYTHONPATH-listed .pth files a higher precedence, see the original commit adding the patch:

注意:此版本包含被黑的"site.py"以支持处理 sys.path上站点软件包之前的目录中的.pth文件.

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

该修补程序早在2006年已从最新的setuptools版本原始的setuptools .

The patch has been removed entirely from more recent setuptools releases, as early as 2006 in the original setuptools.

因此,您的Linux发行版已设置为将lib/python2.7/site-packages添加到您的PYTHONPATH中,或者您的shell为您设置了此设置,或者您的Python已被修补以包含您的site-packages中具有旧的setuptools'patch'.

So, either your Linux distribution has been set up to add lib/python2.7/site-packages to your PYTHONPATH or your shell has this set up for you, or your Python has been patched to include it, and you have the old setuptools 'patch' in your site-packages.

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

It is entirely safe to remove that file.

这篇关于python:lib/site-packages/site.py和lib/site.py之间的相互作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆