2014-09-07 14 views
7

A causa di uno specifico problem che sono riuscito a risolvere, ho passato la maggior parte di oggi a capire come funziona site.py (s). C'è un punto che non capisco.python: Interazione tra lib/site-packages/site.py e lib/site.py

Per quanto ho capito, quando python viene caricato, viene eseguito prima lib/python2.7/site-packages/site.py. Va oltre PYTHONPATH, cerca lib/python2.7/site.py e lo importa. Questo file ha il metodo addsitedir, che non solo aggiunge un percorso a sys.path, ma elabora anche i file *.pth che esistono su di esso. A questo punto, viene eseguito main() da lib/python2.7/site.py e addsitedir viene eseguito sui pacchetti del sito e sui pacchetti del sito utente.

Ora arriva la parte strana. Ora torniamo a lib/python2.7/site-packages/site.py, che va su ogni percorso in pythonpath, ed esegue addsitedir su di esso. Trovo questo strano per due motivi:

  1. addsitedir viene eseguito su lib/python2.7/site-packages due volte.
  2. Questo non è così male in sé (nulla può essere aggiunto a sys.path due volte), ma sembra che lib/python2.7/site.py ha un meccanismo per consentire all'utente di manipolare ambizioso sys.path implementando un modulo usercustomize (ehi, è anche in docs). Ovviamente, quando si implementa un tale meccanismo, si desidera assicurarsi che l'utente entri per ultimo, in modo che possa avere il controllo su tutto aggiunto a sys.path. Ma questo non è il caso qui (come ero frustrato di scoprire). Molto probabilmente, la seconda chiamata a lib/python2.7/site-packages sostituirà tutto ciò che viene fatto in usercustomize.

So che è terribile, ma ho aggiunto una dichiarazione di stampa a addsitedir, stampando il percorso che riceve, così ho potuto mostrare cosa sta succedendo. Questi sono i percorsi elaborati:

/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 

Quindi, che cosa sto chiedendo qui? :)

A. Gradirei approfondimenti sul motivo per cui è necessaria la seconda chiamata ai pacchetti del sito.

B. Il numero usercustomize è davvero limitato poiché credo che sia dovuto a questa implementazione? Considerando questo, come implementeresti qualcosa rimuovendo i percorsi da sys.path (in teoria)?


richiesto output di debug:

: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 
>>> 

uscita di python -vv è here

risposta

8

Il file lib/python2.7/site-packages/site.py è normalmente non caricato. Questo perché è il lavoro di lib/python2.7/site.py aggiungere i percorsi site-packages allo sys.path per iniziare e loin site-packages non è visibile. Se si dispone di unin site-packages allora questo è un errore, non ci dovrebbe essere nessun file lì.

Cosa accade in un pitone patch senza è:

  • Python inizia, con un numero limitato sys.path. site-packages è non fa parte di questo elenco, a meno che non si imposti una variabile PYTHONPATH che lo include comunque.
  • Python importa site.py, importa quello elencato per primo su sys.path.
  • lib/python2.7/site.py viene rilevato e caricato
  • site.py aggiunge site-packages a sys.path

Ecco, ulteriori site.py moduli vengono caricati. Anche se avessi provato, avrebbe trovato il modulo che era già importato; sys.modules['site'] esiste e contiene oggetti caricati da lib/python2.7/site.py.

L'installazione, tuttavia, ha un vecchio setuptools installato, e comprende una special version of site.py, che il comando easy_installwill install into site-packages se non ancora presente. Caricherà l'originale con qualsiasi PYTHONPATH -sostituiti percorsi ignorati e loading the original site.py module manually utilizzando le funzioni di livello basso imp.find_module() e imp.load_module(), ignorando così la normale cache dei moduli.

Il suo intento era quello di modificare l'ordine di dare sys.pathPYTHONPATH -listed .pth file una precedenza maggiore, vedere la original commit adding the patch:

Nota: questa versione include un 'site.py' hacked per supportare l'elaborazione . pth file nelle directory che arrivano prima dei pacchetti del sito su sys.path.

La patch è stata completamente rimossa dalle più recenti versioni setuptools, as early as 2006 in the original setuptools.

Quindi, o la distribuzione Linux è stato istituito per aggiungere lib/python2.7/site-packages al vostro PYTHONPATH o la shell ha questo set up per voi, o il vostro Python è stato aggiornato per includere esso, e si ha la vecchia setuptools 'di patch 'nel tuo site-packages.

È completamente sicuro rimuovere tale file.

+0

Questa risposta è definitiva ed estremamente utile. Molto probabilmente, 'site-packages/site.py' proviene dall'installazione di ** setuptools **. Il * vecchio modo * di installarlo su un'installazione personalizzata di Python [impostazione richiesta PYTHONPATH] (http://askbot.org/en/question/2492/how-to-install-python-easy_install-python-distutils-in-root -o-non-root-conto /). Tuttavia, easy_install [non richiede più questo] (https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations). "[A] ll di questi [vecchi modi] sono effettivamente deprecati dallo schema Utente introdotto da PEP-370 in Python 2.6." – cdunn2001

Problemi correlati