Josue Kouka

Josue Kouka

Code, Linux, and open source — one post at a time.

12 Jan 2015

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.