Importer un module depuis un dossier cachee en python
Il arrive des cas ou pour certaines raisons, on voudrait loader un module python se trouvant dans un repertoire caché ( .myfolder/mymodule). Dans mon cas, je devais charger un fichier settings.py contenu dans le dossier de config de mon app ( ~/.monapp/settings.py). Si vous etes dans la meme situation et vous vous demandez comment le faire, ce qui suit peut vous etre utile:
josue@LokingMac:/tmp/tests$tree -a
.
├── .myapp
│ ├── settings.py
│ └── settings.pyc
└── run.py
1 directory, 3 files
josue@LokingMac:/tmp/tests$
Notre fichier .myapp/settings.py qui correspond au module a importer
import os
def get_realpath(name='.'):
return os.path.realpath(name)
LOG_FILENAME = 'myapp.logs'
LOG_FILESIZE = 1 * 1024 * 1024
Pour importer ce module depuis un run.py par exemple :
import os
import imp
settings = imp.load_source('settings', os.path.realpath('.myapp/settings.py'))
from settings import LOG_FILENAME, LOG_FILESIZE
print(LOG_FILENAME, LOG_FILESIZE)
Execution
josue@LokingMac:/tmp/tests$python run.py
('myapp.logs', 1048576)
josue@LokingMac:/tmp/tests$
Le module a retenir est imp
NB : IL MARCHE POUR TOUT
Mise a jour : imp est mort, vive importlib
Le module imp a ete deprecie depuis Python 3.4 et retire completement en Python 3.12 : le code ci-dessus ne
fonctionne plus tel quel sur une installation recente. L’equivalent moderne est importlib.util :
import importlib.util
import os
path = os.path.realpath('.myapp/settings.py')
spec = importlib.util.spec_from_file_location('settings', path)
settings = importlib.util.module_from_spec(spec)
spec.loader.exec_module(settings)
print(settings.LOG_FILENAME, settings.LOG_FILESIZE)
Meme idee (charger un module Python depuis un chemin de fichier arbitraire), mais spec_from_file_location /
module_from_spec / exec_module est la voie supportee aujourd’hui.
