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

时间:2014-09-07 21:41:16

标签: python linux python-2.7 sys.path

由于我设法解决了一个特定的problem,我今天花了大部分时间来弄清楚site.py是如何工作的。有一点我不明白。

据我所知,加载python时,首先运行lib/python2.7/site-packages/site.py。它会越过PYTHONPATH,搜索lib/python2.7/site.py并导入它。此文件具有addsitedir方法,不仅可以添加sys.path的路径,还可以处理其中存在的*.pth个文件。此时,main()的{​​{1}}已运行,lib/python2.7/site.py在网站包和用户网站包上运行。

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

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

    我知道这很糟糕,但是我向lib/python2.7/site-packages添加了一个打印声明,打印了它收到的路径,这样我就可以显示正在发生的事情。这些是处理的路径:

    usercustomize

    那我在这问什么? :)

    一个。我很欣赏为什么需要第二次调用站点包。

    B中。是addsitedir确实有限,因为我认为这是由于这个实施?考虑到这一点,你将如何从sys.path中实现删除路径(理论上)?


    请求的调试输出:

    /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
    

    usercustomize的输出为here

1 个答案:

答案 0 :(得分:9)

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

没有修补的Python会发生什么:

  • Python以有限site-packages开始。 PYTHONPATH 不属于此列表,除非您设置了包含它的site.py变量。
  • Python导入sys.path,它会导致lib/python2.7/site.py上首先列出的那个。
  • 找到并加载
  • site.py
  • site-packagessys.path添加到site.py

那就是它,没有加载更多的sys.modules['site']模块。即使您尝试过,也会找到已导入的模块; lib/python2.7/site.py存在并保存从setuptools加载的对象。

但是,您的安装安装了较早的easy_install,其中包含special version of site.pysite.py命令will install into site-packages(如果尚未出现)。它会通过使用loading the original site.py module manually和{{imp.find_module()显式扫描原始sys.path,并忽略任何PYTHONPATH提供的路径并imp.load_module()来加载原始sys.path 3}}低级函数,从而绕过正常的模块缓存。

其意图是更改PYTHONPATH订单,以便为.pth列出的setuptools个文件提供更高的优先级,请参阅original commit adding the patch

  

注意:此版本包含一个被黑客攻击的网站。'支持处理   在sys.path上的 site-packages之前的目录中的.pth文件。

该修补程序已完全从最新的lib/python2.7/site-packages版本as early as 2006 in the original setuptools中删除。

因此,您的Linux发行版已经设置为将PYTHONPATH添加到您的setuptools,或者您的shell已经为您设置了这个,或者您的Python已经修补以包含它,并且您拥有旧版site-packages'补丁'在{{1}}中。

删除该文件完全安全。