2014-12-09 3 views
23

Wie kann ich ein Python-Modul in Python 3.4 mit seinem vollständigen Pfad laden?Python 3.4: Wie importiere ich ein Modul mit dem vollständigen Pfad?

Eine ähnliche Frage How to import a module given the full path? behandelt Python-Versionen vor 3.4, aber die Schlussfolgerung ist, dass die Unterstützung in Python 3.4 für die vorgestellten Antworten veraltet ist, so dass jede Lösung für Python 3.4 geschätzt wird.

Beachten Sie, dass diese Frage nicht ein Duplikat Import abitrary python source file. (Python 3.3+) ist, da Antworten für diese auch loader.load_module() zu verwenden, die 3.4 in Python veraltet ist, wie in answer sagte, mit Details in Consider leaving importlib.abc.Loader.load_module() und Dokumentation in importlib.

So wird eine unterstützte Lösung für den Modulimport durch den vollständigen Pfad in Python 3.4 benötigt.

+0

möglich Duplikat [Import abitrary Python-Quelldatei. (Python 3.3+)] (http://stackoverflow.com/questions/19009932/import-abitrary-python-source-file-python-3-3) – falsetru

+7

Schließen Sie nicht. Die Antwort für 3.3+ funktioniert nicht in 3.4, wie von http://stackoverflow.com/a/67692 –

Antwort

9

Dies sollte für alle Python-Dateien arbeiten, unabhängig von der Dateierweiterung:

import importlib.machinery 

modulename = importlib.machinery.SourceFileLoader('modulename','/Path/To/module.py').load_module() 

Diese Methode wurde in der deprecation Nachricht im imp.load_moduledocumentation erwähnt.

+0

Danke für den Hinweis, und es sieht in aktuellen Python 3.4 voll unterstützt, so dass das muss der Ersatz sein, also die Antwort :-) – EquipDev

+2

FYI: Veraltet seit Version 3.6: Verwenden Sie stattdessen importlib.abc.Loader.exec_module(). [Quelle] (https://docs.python.org/3/library/importlib.html) – Trolldejo

0

Die folgende Funktion funktioniert in Python 3.4 - es wird verwendet, um bestimmte Funktionen in Modulen zu laden und auszuführen, aber Sie müssen den Ordner zum Pfad sys hinzufügen.

sys.path.append("path_to_your_file_to_import") 
tool = {'file':'test_tool.py', 
    'function':'sum_even_numbers', 
    'args':['list'], 
    'return':['int'] 
} 

args = [1,2,3] 

def run(tool, args, silent='Y'): 
     if silent == 'N': 
      print('main called ' + tool['file'] + '->' + tool['function'] + ' with ', args, ' = ', tool['return']) 
     mod = __import__(os.path.basename(tool['file']).split('.')[0]) 
     func = getattr(mod, tool['function']) 
     tool['return'] = func(args) 
     return tool['return'] 

Nennen Sie es über

run(tool, args) 
+0

angegeben. Dies ist nur einfach "Import" basierend auf Namen, wie die Anweisung "import test_tool", und nicht importieren von ein Modul an einem bestimmten Ort (Pfad). Der "self" -Teil bewirkt, dass er wie ein Copy-Paste-Objekt aus einer Klasse aussieht. Daher führt der einfache Aufruf von 'run (tool, args)' zu einem Syntaxfehler. – EquipDev

+0

@EquipDev Sie haben Recht - der Ordner muss zum sys-Pfad hinzugefügt werden. Ich habe bearbeitet, um dies zu zeigen, und entfernte auch den Selbstparam. Es war von einer Klasse, die ich arbeite - https://github.com/acutesoftware/AIKIF/blob/master/aikif/tools.py – acutesoftware

+0

Mit dem regulären Import (__import__) mechanish mit 'sys.path' wird nicht zulassen Sie importieren ein Modul im Dateinamen "sys.py", da dies mit dem integrierten 'sys'-Modul kollidieren wird. – EquipDev

2

Die bereits gegebene Antwort funktioniert, ist aber unnötig klobig. Eine einfachere Methode:

import sys, os, importlib 

sys.path.append(os.path.dirname(filename)) 
mname = os.path.splitext(os.path.basename(filename))[0] 
imported = importlib.import_module(mname)      
sys.path.pop() 

imported ist das importierte Modul; Sie können es wie gewohnt verwenden, imported.method(arg). Die letzte Zeile ist nicht unbedingt notwendig, aber es ist sauberer, keine unnötigen Einträge in sys.path zu hinterlassen (besonders, wenn Sie den Code mehrmals ausführen). Dies funktioniert in 3.4 und verwendet nichts, das als veraltet markiert ist.

+0

Wenn '' mname'' "/my/own/dir/stat.py" ist, dann wird der Code das Python-Standardbibliothek-Modul '' stat'' importieren, und nicht das angegebene Modul, weil der Name versehentlich zusammentrifft mit einem Modul in der Python Standard Library. Das funktioniert also nicht in allen Fällen. – EquipDev

+1

Wahr. Ich denke, aber ich bin mir nicht sicher, ob dies durch 'sys.path.insert (0, os.path.dirname (filename))' statt '.append()' behoben werden kann (und natürlich '' .pop (0) 'danach). Hängt davon ab, ob 'sys.path' eine Standard-Suchpfad-Semantik hat. Wenn Sie dies tun, ist es natürlich noch wichtiger, den folgenden Eintrag zu entfernen, um zu verhindern, dass Dateien in diesem Verzeichnis die Standardbibliothek überschatten. (Auf einer grundlegenderen Ebene ist es wahrscheinlich eine schlechte Idee, Ihre Module sowieso als Standard-Bibliotheksmodule zu bezeichnen. Aber.) –

+0

Ja, es kann in diesem Fall helfen, aber andere Module, die es gibt Der Name als Standardbibliothek kann dann eine Standardbibliothek überschatten. Stimmen Sie zu, dass Sie die Verwendung vorhandener Standardbibliotheksmodulnamen vermeiden sollten. Aber ich denke, dass all diese Umgehungsaspekte Symptome sind, dass es eine einfache Möglichkeit gibt, eine Datei einfach als Modul zu importieren ... genau wie es in früheren Versionen von Python möglich war. – EquipDev

2

Die unterstützte und Verfahren nicht veraltet nach der 3.6 docs ist wie folgt:

def import_file(full_name, path): 
    """Import a python module from a path. 3.4+ only. 

    Does not call sys.modules[full_name] = path 
    """ 
    from importlib import util 

    spec = util.spec_from_file_location(full_name, path) 
    mod = util.module_from_spec(spec) 

    spec.loader.exec_module(mod) 
    return mod 
Verwandte Themen