| Scopo | Espone l'implementazione dell'istruzione Python import. |
| Versione Python | 2.2.1 e superiore |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per le versioni 3.x di Python
Il modulo imp comprende funzioni che espongono parte dell'implementazione sottostante il meccanismo di importazione di Python per caricare il codice in pacchetti e moduli. E' un punto di accesso per l'importazione dinamica di moduli, ed è utile in alcuni casi laddove non si conosce il nome del modulo che occorre importare quando si sta scrivendo il proprio codice (es. per plugin od estensioni di una applicazione).
Gli esempi seguenti usano un pacchetto chiamato "example" con __init__py:
print 'Importazione del pacchetto example'
ed un modulo chiamato submodule che contiene:
print 'Importazione di submodule'
Si osservi il testo stampato dalle istruzioni print nell'output di esempio quando il pacchetto od il modulo sono importati.
Python supporta parecchi stili di moduli. Ognuno dei quali richiede la sua propria gestione in fase di apertura ed aggiunta allo spazio dei nomi. Alcuni dei tipi supportati ed i loro parametri possono essere elencati dalla funzione
get_suffixes()
.
import imp
module_types = { imp.PY_SOURCE: 'sorgente',
imp.PY_COMPILED: 'compilato',
imp.C_EXTENSION: 'estensione',
imp.PY_RESOURCE: 'risorsa',
imp.PKG_DIRECTORY: 'pacchetto',
}
def main():
fmt = '%10s %10s %10s'
print fmt % ('Estensione', 'Modalità', 'Tipo')
print '-' * 32
for extension, mode, module_type in imp.get_suffixes():
print fmt % (extension, mode, module_types[module_type])
if __name__ == '__main__':
main()
get_suffixes()
restituisce una sequenza di tuple che contiene l'estensione del file, la modalità usata per aprire il file, ed un tipo codice ottenuto da una costante definita nel modulo. Questa tabella è incompleta, poichè alcuni dei moduli o tipi di pacchetto importabili non corrispondono a singoli file.
$ python imp_get_suffixes.py
Estensione Modalità Tipo
--------------------------------
.so rb estensione
module.so rb estensione
.py U sorgente
.pyc rb compilato
Il primo passo per caricare un modulo è trovarlo.
find_module()
scorre il percorso di ricerca di importazione cercando un pacchetto o modulo con il nome fornito. Restituisce un handle di file aperto (se appropriato per il tipo),
filename
(il nome del file) dove il modulo è stato trovato, e
description
(una tupla tipo quella restituita da
get_suffixes()
).
import imp
from imp_get_suffixes import module_types
print 'Pacchetto:'
f, filename, description = imp.find_module('example')
print module_types[description[2]], filename
print
print 'Sub-modulo:'
f, filename, description = imp.find_module('submodule', [filename])
print module_types[description[2]], filename
if f: f.close()
$ python imp_find_module.py Pacchetto: pacchetto /home/robby/pydev/pymotw-it/dumpscripts/example Sub-modulo: sorgente /home/robby/pydev/pymotw-it/dumpscripts/example/submodule.py
Se
find_module
non riesce a trovare il modulo, solleva una eccezione
ImportError
.
import imp
try:
imp.find_module('modulo_che_non_esiste')
except ImportError, err:
print 'ImportError:', err
$ python imp_find_module_error.py ImportError: No module named modulo_che_non_esiste
Una volta che si è trovato il modulo si usa
load_module()
per importarlo effettivamente.
load_module()
riceve il percorso completo del modulo (punti inclusi) ed i valori restituiti da
find_module()
(la tupla con l'handle di file aperto, il nome del file e la descrizione).
import imp
f, filename, description = imp.find_module('example')
example_package = imp.load_module('example', f, filename, description)
print 'Pacchetto:', example_package
f, filename, description = imp.find_module('submodule',
example_package.__path__)
try:
submodule = imp.load_module('example.module', f, filename, description)
print 'Sub-modulo:', submodule
finally:
f.close()
load_module()
crea un nuovo oggetto modulo con il nome fornito, carica il codice contenuto, quindi lo aggiunge a sys.modules
$ python imp_load_module.py Importazione del pacchetto example Pacchetto:Importazione di submodule Sub-modulo:
Chiamando
load_module()
per un modulo che è già stato importato, si ottiene lo stesso effetto della chiamata di
reload()
sull'oggetto modulo esistente
import imp
import sys
for i in range(2):
print i,
try:
m = sys.modules['example']
except KeyError:
print '(non in sys.modules)',
else:
print '(presente in sys.modules)',
f, filename, description = imp.find_module('example')
example_package = imp.load_module('example', f, filename, description)
Invece di creare un nuovo modulo, il contenuto del modulo esistente viene semplicemente rimpiazzato.
$ python imp_load_module_reload.py 0 (non in sys.modules) Importazione del pacchetto example 1 (presente in sys.modules) Importazione del pacchetto example
Vedere anche: