2014-09-07 2 views
7

특정 problem으로 해결할 수 있었기 때문에 저는 오늘날 대부분의 사람들이 site.py()의 작동 방식을 파악했습니다. 내가 이해하지 못하는 점이있다.python : lib/site-packages/site.py와 lib/site.py 사이의 상호 작용

필자가 아는 한, 파이썬이로드 될 때, 먼저 lib/python2.7/site-packages/site.py이 실행됩니다. PYTHONPATH 이상이고 lib/python2.7/site.py을 검색하여 가져옵니다. 이 파일은 addsitedir 메서드를 가지고 있으며, sys.path에 대한 경로를 추가 할뿐만 아니라 거기에 존재하는 *.pth 개의 파일도 처리합니다. 이 시점에서 main()lib/python2.7/site.py이고, 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에 print 문을 추가 했으므로 어떤 일이 벌어 지는지 보여줄 수있었습니다. 다음은 처리 된 경로입니다.

/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 

그래서 내가 뭘 물어 보는거야? :)

A. 이유는 사이트 패키지에 대한 두 번째 호출이 필요한 이유입니다.

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의는 lib/python2.7/site-packages/site.py 파일이 정상적으로로드되지 입니다 here

답변

8

입니다. 이는 의 작업이 sys.path에 처음으로 site-packages 경로를 추가하고 site.pysite-packages 인 경우 표시되지 않기 때문입니다. site.pysite-packages 인 경우 오류입니다. 해당 파일이 없어야합니다.없이 패치되지 않은 파이썬에서 어떻게됩니까

은 다음과 같습니다

  • 파이썬은 제한된 sys.path로 시작합니다. site-packages은이 아니며 PYTHONPATH 변수를 포함하지 않는 한 입니다.
  • 파이썬이 site.py을 가져 오면 sys.path에 처음 나열된 언어를 가져옵니다.
  • lib/python2.7/site.py
  • 발견하고
  • site.pysite-packages 다야 것을 더 site.py 모듈이 장착되지

sys.path로드에 추가된다. 시도해도 이 이미 가져온 모듈을 찾을 수 있습니다.; sys.modules['site']이 존재하고 lib/python2.7/site.py에서로드 된 개체를 보유하고 있습니다.

귀하의 설치는, 그러나, setuptools 설치 이전이 있고, 아직 존재하는 easy_install 명령 will install into site-packages 아닌 경우 special version of site.py가 포함되어 있습니다. 명시 적으로 원본을 sys.path으로 스캔하여 PYTHONPATH 제공 경로를 무시하고 loading the original site.py module manuallyimp.find_module()imp.load_module() 낮은 수준 기능을 사용하여 일반 모듈 캐시를 우회하여 원래의 site.py을로드합니다.

참고 :이 버전은 처리 을 지원하는 해킹 'site.py'를 포함

그것의 목적은 original commit adding the patch를 참조 PYTHONPATH -listed .pth가 더 높은 우선 순위를 파일을 제공 할 수있는 sys.path 순서를 변경하는 것이 었습니다. sys_path에 site-packages 앞에 이 오는 디렉토리의 pth 파일.

패치는 최신 setuptools 릴리스 as early as 2006 in the original setuptools에서 완전히 제거되었습니다.

그래서 어느 리눅스 배포판은 당신의 PYTHONPATHlib/python2.7/site-packages를 추가하도록 설정되었거나 쉘이 당신을 위해 설정 한 또는 파이썬을 포함하도록 패치 된, 가와 당신은 이전 setuptools '패치가 '이 (가) site-packages입니다.

해당 파일을 완전히 삭제하는 것이 안전합니다.

+0

이 답변은 명확하고 매우 유용합니다. 대부분의 경우,'site-packages/site.py'는 ** setuptools **를 설치 한 것이 었습니다. 커스텀 파이썬 설치에 설치하는 * 옛 방식 * [필수 설정 PYTHONPATH] (http://askbot.org/ko/question/2492/how-to-install-python-easy_install-python-distutils-in-root - 또는 - 비 - 루트 계정 /). 그러나 easy_install [더 이상 필요하지 않습니다] (https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations). "Python 2.6에서 PEP-370에 의해 도입 된 User 체계에 의해 이러한 [오래된] 방법이 효과적으로 사용되지 않게되었습니다." – cdunn2001