Frage Wie importiere ich ein Modul mit dem vollständigen Pfad?


Wie kann ich ein Python-Modul mit seinem vollständigen Pfad laden? Beachten Sie, dass sich die Datei an einer beliebigen Stelle im Dateisystem befinden kann, da es sich um eine Konfigurationsoption handelt.


774
2017-09-15 22:30


Ursprung


Antworten:


Für Python 3.5+ verwenden Sie:

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()

Für Python 3.3 und 3.4 verwenden Sie:

from importlib.machinery import SourceFileLoader

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

(Obwohl dies in Python 3.4 veraltet ist.)

Python 2 benutzt:

import imp

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

Es gibt entsprechende Komfortfunktionen für kompilierte Python-Dateien und DLLs.

Siehe auch. http://bugs.python.org/issue21436.


898
2017-09-15 22:41



Der Vorteil des Hinzufügens eines Pfades zu sys.path (über die Verwendung von imp) besteht darin, dass es beim Importieren von mehr als einem Modul aus einem einzelnen Paket die Dinge vereinfacht. Beispielsweise:

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



Sie können auch so etwas machen und das Verzeichnis, in dem sich die Konfigurationsdatei befindet, dem Python-Ladepfad hinzufügen und dann einen normalen Import durchführen, vorausgesetzt, Sie kennen den Namen der Datei im Voraus, in diesem Fall "config".

Unordentlich, aber es funktioniert.

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



Du kannst den ... benutzen

load_source(module_name, path_to_file) 

Methode von IMP-Modul.


16
2017-09-15 22:41



Es klingt so, als ob Sie die Konfigurationsdatei (die eine ganze Reihe von Nebeneffekten und zusätzlichen Komplikationen beinhaltet) nicht speziell importieren, sondern nur ausführen und auf den resultierenden Namespace zugreifen wollen. Die Standardbibliothek stellt dafür eine API in Form von runpy.run_path:

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

Diese Schnittstelle ist in Python 2.7 und Python 3.2+ verfügbar


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



Meinst du laden oder importieren?

Sie können die Liste sys.path bearbeiten, indem Sie den Pfad zu Ihrem Modul angeben und dann Ihr Modul importieren. Zum Beispiel, ein Modul gegeben an:

/foo/bar.py

Du könntest es tun:

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



Ich glaube, du kannst es benutzen imp.find_module() und imp.load_module() um das angegebene Modul zu laden. Sie müssen den Modulnamen vom Pfad trennen, d. H. Wenn Sie laden wollten /home/mypath/mymodule.py Sie müssten tun:

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

... aber das sollte die Arbeit erledigen.


8
2017-09-15 22:37



Hier ist ein Code, der in allen Python-Versionen von 2.7-3.5 und wahrscheinlich sogar anderen funktioniert.

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

Ich habe es getestet. Es kann hässlich sein, aber bis jetzt ist es das einzige, das in allen Versionen funktioniert.


7
2018-06-03 10:04