site - Configurazione a Livello di Sito
Scopo: Gestisce configurazioni specifiche al sito, in particolare il percorso di importazione
Percorso di Importazione
Il modulo site viene importato automaticamente ogni volta che viene fatto partire l'interprete. In importazione, estende sys.path
con nomi specifici al sito, costruiti combinando i valori di prefisso sys.prefix
e sys.exec_prefix
con parecchi suffissi. I valori di prefisso usati sono salvati nella variabile a livello di modulo PREFIXES
per riferimenti successivi. Sotto Windows, i suffissi sono un stringa vuota e lib/site-packages
. Per le piattaforme tipo Unix i valori sono lib/python$version/site-packages
(dove $version
viene sostituita dai numeri di versione maggiore e minore dell'interprete, tipo 3.5) e lib/site-python
.
# site_import_path.py
import sys
import os
import site
if 'Windows' in sys.platform:
SUFFIXES = [
'',
'lib/site-packages',
]
else:
SUFFIXES = [
'lib/python{}/site-packages'.format(sys.version[:3]),
'lib/site-python',
]
print('Prefissi percorso:')
for p in site.PREFIXES:
print(' ', p)
for prefix in sorted(set(site.PREFIXES)):
print()
print(prefix)
for suffix in SUFFIXES:
print()
print(' ', suffix)
path = os.path.join(prefix, suffix).rstrip(os.sep)
print(' esiste:', os.path.exists(path))
print(' in percorso:', path in sys.path)
Ciascun percorso risultante dalle combinazioni viene verificato, e quelli che esistono vengono aggiunti a sys.path
. Questo risultato mostra la versione dell'impianto di Python installato su di un sistema Linux.
$ python3 site_import_path.py Prefissi percorso: /dati/dev/python/pymotw3restyling/.venv /dati/dev/python/pymotw3restyling/.venv lib/python3.8/site-packages esiste: True in percorso: True lib/site-python esiste: False in percorso: False
Directory Utente
Oltre ai percorsi globali dei pacchetti del sito, site è responsabile dell'aggiunta delle locazioni specifiche utente al percorso di importazione. I percorsi specifici utente sono tutti basati sulla directory USER BASE
, che in genere si trova in una parte del file sistema nella quale l'utente corrente possa leggere e scrivere. All'interno della directory USER BASE
si trova una directory site-packages
, con il percorso accessibile come USER SITE
.
# site_user_base.py
import site
print('Base:', site.USER_BASE)
print('Site:', site.USER_SITE)
Il nome del percorso per USER SITE
viene creato usando gli stessi valori di suffisso specifici alla piattaforma sopra descritti.
$ python3 site_user_base.py Base: /home/robby/.local Site: /home/robby/.local/lib/python3.8/site-packages
La directory base dell'utente può essere impostata tramite la variabile di ambiente PYTHONUSERBASE
, ed ha valori predefiniti specifici alla piattaforma (~/Python$version/site-packages
per Windows e ~/.local
per non Windows).
$ PYTHONUSERBASE=/tmp/ python3 site_user_base.py Base: /tmp/robby Site: /tmp/robby/lib/python3.8/site-packages
La directory base dell'utente viene disabilitata in particolari circostanze che potrebbero porre problemi di sicurezza (ad esempio se il processo viene eseguito da un utente effettivo diverso oppure da un id di gruppo diverso da quello dell'utente effettivo che lo ha fatto partire). Un'applicazione può verificare l'impostazione esaminando ENABLE_USER_SITE
.
# site_enable_user_site.py
import site
status = {
None: 'Disabilitato, ragioni di sicurezza',
True: 'Abilitato',
False: 'Disabilitato da opzione riga di comando',
}
print('Flag :', site.ENABLE_USER_SITE)
print('Significato:', status[site.ENABLE_USER_SITE])
Anche la directory dell'utente può essere esplicitamente disabilitata nella riga di comando con -s.
$ python3 site_enable_user_site.py Flag : False Significato: Disabilitato da opzione riga di comando
$ python3 -s site_enable_user_site.py Flag : False Significato: Disabilitato da opzione riga di comando
File di Configurazione Percorsi
Mano a mano che i percorsi sono aggiunti al percorso di importazione sono anche verificati alla ricerca di file di configurazione percorso. Si tratta di file a testo semplice con estensione .pth
. Ogni riga nel file può avere uno dei seguenti formati:
- Un percorso completo o relativo a un'altra locazione che dovrebbe essere aggiunta al percorso di importazione.
- Una istruzione Python da eseguire. Righe di questo tipo dovrebbero iniziare con una istruzione
import
. - Le righe vuote sono ignorate.
- Una riga che inizia con
#
viene considerata un commento e ignorata.
I file di configurazione percorso possono essere usati per estendere il percorso di importazione affinchè vengano cercate locazioni che non sarebbero state aggiunte automaticamente. Ad esempio il pacchetto setuptools
aggiunge un percorso ad easy-install.pth
quando installa un pacchetto in modalità sviluppo usando python setup.py develop
.
La funzione per estendere sys.path
è pubblica, e può essere usata nei programmi di esempio per mostrare come funzionano i file di configurazione percorso. Data una directory chiamata con_moduli
che contiene il file miomodulo.py
con l'istruzione print
di seguito si mostra come il modulo viene importato.
# con_moduli/miomodulo.py
import os
print('Caricato {} da {}'.format(
__name__, __file__[len(os.getcwd()) + 1:])
)
Questo script mostra come addsitedir()
estende il percorso di importazione in modo che l'interprete possa trovare il modulo desiderato.
# site_addsitedir.py
import site
import os
import sys
script_directory = os.path.dirname(__file__)
module_directory = os.path.join(script_directory, sys.argv[1])
try:
import miomodulo
except ImportError as err:
print('Non posso importare mioodulo:', err)
print()
before_len = len(sys.path)
site.addsitedir(module_directory)
print('Nuovi percorsi:')
for p in sys.path[before_len:]:
print(p.replace(os.getcwd(), '.')) # nome directory abbreviato
print()
import miomodulo
Dopo che la directory che contiene il modulo viene aggiunta a sys.path
, lo script può importare il modulo specifico senza problemi.
$ python3 site_addsitedir.py con_moduli Non posso importare mioodulo: No module named 'miomodulo' Nuovi percorsi: ./con_moduli Caricato miomodulo da con_moduli/miomodulo.py
Le modifiche al percorso effettuate da addsitedir()
vanno oltre il semplice accodamento dell'argomento a sys.path
. Se la directory passata a addistedir()
include qualsiasi file che trova corrispondenza con il modello *.pth
, che viene caricato come file di configurazione di percorso. Data la seguente struttura di directory:
con_pth |____ pymotw.pth |____ sottodirectory |____ miomodulo.py
Se con_pth/pymotw.pth
contiene.
# Aggiunte una singola sottodirectory al percorso
./sottodirectory
allora con_pth/sottodirectory/miomodulo.py
può essere importato aggiungendo con_pth
come directory di sito, anche se il modulo non si trova in quella directory visto che sia con_pth
che con_pth/sottodirectory
sono aggiunte al percorso di importazione.
$ python3 site_addsitedir.py con_pth Non posso importare mioodulo: No module named 'miomodulo' Nuovi percorsi: ./con_pth ./con_pth/sottodirectory
Se una directory sito contiene file .pth
multipli, sono elaborati in ordine alfabetico.
$ ls -F pth_multipli a.pth b.pth da_a/ da_b/
$ cat pth_multipli/a.pth ./da_a
$ cat pth_multipli/b.pth ./da_b
In questo caso il modulo viene trovato in pth_multipli/da_a
in quanto a.pth
viene letto prima di b.pth
.
$ python3 site_addsitedir.py pth_multipli Non posso importare mioodulo: No module named 'miomodulo' Nuovi percorsi: ./pth_multipli ./pth_multipli/da_a ./pth_multipli/da_b Caricato miomodulo da pth_multipli/da_a/miomodulo.py
Personalizzare la Configurazione di Site
Il modulo site è anche responsabile per il caricamento di personalizzazioni a livello di sito definite dal possessore locale del sito in un modulo sitecustomize
. Gli utilizzi per sitecustomize
includono l'estendere il percorso di importazione e l'abilitare strumenti di analisi della copertura del codice, profilazione o altri strumenti di sviluppo.
Ad esempio lo script sitecustomize.py
estende il percorso di importazione con una directory basata sulla piattaforma corrente. Viene aggiunto al percorso di importazione un percorso specifico alla piattaforma in /opt/python
, in modo che qualunque pacchetto ivi installato potrà essere importato. Un sistema come questo è utile per condividere tra host in una rete via file system condiviso pacchetti che contengono estensioni di moduli compilati. Occorre installare in ciascun host solo lo script sitecustomize.py
e gli altri pacchetti saranno indirizzati dal file server.
# con_personalizzazioni_sito/sitecustomize.py
print('Caricamento di sitecustomize.py')
import site
import platform
import os
import sys
path = os.path.join('/opt',
'python',
sys.version[:3],
platform.platform(),
)
print('Si aggiunge il nuovo percorso', path)
site.addsitedir(path)
Un semplice script può essere usato per mostrare come sitecustomize.py
venga importato prima che Python inizi a eseguire il proprio codice.
# con_personalizzazioni_sito/site_sitecustomize.py
import sys
print('Esecuzione del programma principale da\n{}'.format(sys.argv[0]))
print('Fine del percorso:', sys.path[-1])
Visto che sitecustomize
è concepito per configurazioni a livello di sistema, dovrebbe essere installato da qualche parte nel percorso predefinito (in genere la directory site-packages
). Questo esempio imposta esplicitamente PYTHONPATH
per assicurarsi che il modulo venga individuato.
$ PYTHONPATH=con_personalizzazione python3 con_personalizzazioni_sito/site_sitecustomize.py Esecuzione del programma principale da con_personalizzazioni_sito/site_sitecustomize.py Fine del percorso: /dati/dev/python/pymotw3restyling/.venv/lib/python3.8/site-packages
Personalizzare la Configurazione Utente
Alla stessa stregua di sitecustomize
, il modulo usercustomize
può essere usato per gestire impostazioni specifiche per l'utente ogni volta che l'interprete viene messo in esecuzione. usercustomize
viene caricato dopo sitecustomize
, in modo che possano essere sovrascritte le configurazioni a livello di sistema.
In ambienti dove la directory home di un utente sia condivisa tra parecchi server che eseguono sistemi operativi o versioni diverse. il meccanismo standard di directory utente potrebbe non funzionare per installazioni di pacchetti specifiche per l'utente. In questi casi, è invece possibile usare una alberatura di directory specifiche alla piattaforma.
# con_personalizzazioni_utente/usercustomize.py
print('Caricamento di usercustomize.py')
import site
import platform
import os
import sys
path = os.path.expanduser(os.path.join('~',
'python',
sys.version[:3],
platform.platform(),
))
print('Aggiunta nuovo percorso', path)
site.addsitedir(path)
Un altro semplice script, simile a quello usato per sitecustomize
, può essere usato per mostrare che usercustomize.py
viene importato prima che Python inizi a eseguire dell'altro codice.
# con_personalizzazioni_utente/site_usercustomize.py
import sys
print('Esecuzione del programma principale da\n{}'.format(sys.argv[0]))
print('Fine del percorso:', sys.path[-1])
Visto che usercustomize
è concepito per configurazioni specifiche per l'utente, dovrebbe essere installato da qualche parte nel percorso predefinito dell'utente, ma non nel percorso a livello di sito. La directory predefinita USER_BASE
è una buona scelta. Questo esempio imposta PYTHONPATH
esplicitamente per assicurarsi che il modulo venga individuato.
$ PYTHONPATH=con_personalizzazioni_utente python3 con_personalizzazioni_utente/site_usercustomize.py Esecuzione del programma principale da con_personalizzazioni_utente/site_usercustomize.py Fine del percorso: /dati/dev/python/pymotw3restyling/.venv/lib/python3.8/site-packages
Quando è disabilitata la caratteristica di directory di sito, usercustomize
non viene importato, a prescindere dalla sua locazione nel file system.
$ PYTHONPATH=con_personalizzazione_utente python3 -s con_personalizzazioni_utente/site_usercustomize.py Esecuzione del programma principale da con_personalizzazioni_utente/site_usercustomize.py Fine del percorso: /dati/dev/python/pymotw3restyling/.venv/lib/python3.8/site-packages
Disabilitare il Modulo site
Per mantenere la compatibilità all'indietro con le versioni di Python, prima che l'importazione automatica venisse aggiunta, l'interprete accetta l'opzione -S
.
$ python3 -S site_import_path.py Prefissi percorso: /usr /usr /usr lib/python3.8/site-packages esiste: False in percorso: False lib/site-python esiste: False in percorso: False
Vedere anche:
- site
- La documentazione della libreria standard per questo modulo.
- Moduli e Import (di prossima traduzione)
- Descrizione di come funzioni il percorso di importazione definito in
sys
. - setuptools
- Strumenti di gestione pacchetti della prossima generazione.
- Running code at Python startup
- Post da Ned Batchelder che discute i modi nei quali si può fare eseguire all'interprete Python codice di inizializzazione personalizzato prima che inizi l'esecuzione del programma principale.