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

Note (2026): This post’s main example uses the imp module, deprecated since Python 3.4 and removed entirely in Python 3.12: it won’t run as-is on a recent install. See the “Mise a jour” section near the bottom for the modern importlib.util equivalent.

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.

Dans la meme veine de petites astuces Python: Attacher une methode a une classe en python et Comprendre *, **, *args, **kwargs.