Question Comment importer un module donné le chemin complet?


Comment puis-je charger un module Python donné son chemin complet? Notez que le fichier peut être n'importe où dans le système de fichiers, car il s'agit d'une option de configuration.


774
2017-09-15 22:30


origine


Réponses:


Pour Python 3.5+, utilisez:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

Pour Python 3.3 et 3.4, utilisez:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(Bien que cela ait été déprécié dans Python 3.4.)

Python 2 utiliser:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

Il existe des fonctions de commodité équivalentes pour les fichiers Python compilés et les DLL.

Voir également. http://bugs.python.org/issue21436.


898
2017-09-15 22:41



L'avantage d'ajouter un chemin à sys.path (sur l'utilisation de imp) est qu'il simplifie les choses lors de l'importation de plus d'un module à partir d'un seul paquet. Par exemple:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch

307
2017-09-24 19:36



Vous pouvez aussi faire quelque chose comme ça et ajouter le répertoire dans lequel se trouve le fichier de configuration au chemin de chargement Python, puis faire une importation normale, en supposant que vous connaissiez le nom du fichier à l'avance, dans ce cas "config".

Sale, mais ça marche.

configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config

17
2017-09-15 22:44



Vous pouvez utiliser le

load_source(module_name, path_to_file) 

méthode de module d'imp.


16
2017-09-15 22:41



Il semble que vous ne souhaitiez pas importer spécifiquement le fichier de configuration (ce qui implique beaucoup d'effets secondaires et de complications supplémentaires), vous souhaitez simplement l'exécuter et accéder à l'espace de noms qui en résulte. La bibliothèque standard fournit une API spécifiquement pour cela sous la forme de runpy.run_path:

from runpy import run_path
settings = run_path("/path/to/file.py")

Cette interface est disponible dans Python 2.7 et Python 3.2+


12
2018-05-20 06:52



def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except:
        raise ImportError

import_file('/home/somebody/somemodule.py')

10
2017-09-16 01:43



Voulez-vous dire charger ou importer?

Vous pouvez manipuler la liste sys.path en spécifiant le chemin d'accès à votre module, puis importer votre module. Par exemple, donné un module à:

/foo/bar.py

Vous pourriez faire:

import sys
sys.path[0:0] = '/foo' # puts the /foo directory at the start of your path
import bar

9
2017-09-15 22:46



Je crois que tu peux utiliser imp.find_module() et imp.load_module() charger le module spécifié. Vous devez séparer le nom du module du chemin, c'est-à-dire si vous voulez charger /home/mypath/mymodule.py vous auriez besoin de faire:

imp.find_module('mymodule', '/home/mypath/')

... mais cela devrait faire le travail.


8
2017-09-15 22:37



Voici du code qui fonctionne dans toutes les versions de Python, de 2.7 à 3.5 et probablement même d'autres.

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())

Je l'ai testé. Il peut être laid mais jusqu'à présent, il est le seul qui fonctionne dans toutes les versions.


7
2018-06-03 10:04



Je suis venu avec une version légèrement modifiée de la réponse merveilleuse de @ SebastianRittau (pour Python> 3.4 je pense), qui vous permettra de charger un fichier avec n'importe quelle extension en tant que module en utilisant spec_from_loader au lieu de spec_from_file_location:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

L'avantage de coder le chemin dans un SourceFileLoader est-ce le machinerie n'essaiera pas de comprendre le type du fichier de l'extension. Cela signifie que vous pouvez charger quelque chose comme un .txt fichier en utilisant cette méthode, mais vous ne pouviez pas le faire avec spec_from_file_location sans spécifier le chargeur car .txt n'est pas dans importlib.machinery.SOURCE_SUFFIXES.


5
2018-04-25 05:45



Cela devrait fonctionner

path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
    basename = os.path.basename(infile)
    basename_without_extension = basename[:-3]

    # http://docs.python.org/library/imp.html?highlight=imp#module-imp
    imp.load_source(basename_without_extension, infile)

3
2018-01-04 02:17