2012-04-15 9 views
44

Ich habe ein Modul foo, mit util.py und bar.py.Importieren Python-Modul nicht auf Pfad

Ich möchte es in IDLE oder Python-Sitzung importieren. Wie gehe ich vor?

Ich konnte keine Dokumentation zum Importieren von Modulen finden, die sich nicht im aktuellen Verzeichnis oder dem Standard-Python PATH befinden. Nach dem Versuch import "<full path>/foo/util.py", und from "<full path>" import util

Der nächste könnte ich bekommen

import imp 
imp.load_source('foo.util','C:/.../dir/dir2/foo') 

Welche mir Erlaubnis auf Fenster verweigert gab 7.

+0

Es lohnt sich auch, diese [verwandte Frage] (http://stackoverflow.com/questions/15109548/set-pythonpath-before-import-statements) zu überprüfen. Insbesondere mag ich die [top Antwort] (http://stackoverflow.com/a/15109660/95852) dort für ihre Klarheit über die Sicherheit von Änderungen an 'sys.path'. –

+0

Mögliches Duplikat von [Wie importiere ich ein Modul mit dem vollständigen Pfad?] (Http://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path) –

Antwort

62

Eine Möglichkeit ist, einfach Ihre path zu ändern:

import sys 
sys.path.append('C:/full/path') 
from foo import util,bar 

Beachten Sie, dass diese foo ein Python-Paket sein erfordert, das heißt eine __init__.py Datei enthalten. Wenn Sie sys.path nicht ändern möchten, können Sie also modify the PYTHONPATH environment variable oder install the module on your system. Beachten Sie, dass andere Verzeichnisse oder .py Dateien in diesem Verzeichnis möglicherweise versehentlich geladen werden.

Daher möchten Sie stattdessen imp.load_source verwenden. Es muss den Dateinamen, kein Verzeichnis (in einer Datei, die der aktuelle Benutzer zu lesen ist erlaubt):

import imp 
util = imp.load_source('util', 'C:/full/path/foo/util.py') 
+0

Es funktioniert, aber jetzt, wenn Sie versuchen, util.method mit der Methode zu verwenden, heißt es "Methode" nicht definiert. Aber ich kann es mit util.method verwenden. Warum? – Vort3x

+2

Weil Sie 'method' nicht definiert haben, nur die' Methode' in 'util'". Sie können 'method = util.method' definieren, wenn Sie möchten. – katrielalex

+0

Beachten Sie, dass 'from foo import *' schlecht codiert ist, es sei denn, Sie hacken nur in der Shell herum. – katrielalex

5

Sie könnten den Modulsuchpfad mit der PYTHONPATH Umgebungsvariable anpassen oder ändern Sie die Verzeichnisliste sys.path manuell.

Siehe Module Search Path Dokumentation auf python.org.

2

diese versuchen ein Geben

import sys 
sys.path.append('c:/.../dir/dir2') 
import foo 
+1

-1 Weil das Anhängen an den Python-Pfad eine schlechte Lösung ist. Es funktioniert, aber es ist streng schlechter als imp.load_source, da der Benutzer möglicherweise keine Systempfade ändern möchte oder an einem Computer arbeitet, auf dem er oder sie das nicht tun kann. Dies ist tatsächlich eine der nervigsten "Funktionen" in Python, die ansonsten eine elegante Sprache ist. Es ist albern, dass Sie nicht einfach eine Zeichenfolge übergeben können, die einen Pfad zu einer anderen .py-Datei angibt.Und wenn man das nicht kann, ist der Schutz vor Systemänderungen durch Verwendung von IMP strikt besser. – ely

+1

@EMS Ah .. Ich sehe, was Sie sagen, ich habe es vorher nicht bemerkt, aber jetzt ist der Punkt, den Sie machen, klar. Danke, dass du darauf hingewiesen hast. (Ich muss vielleicht jetzt etwas von meinem eigenen Code ändern :) – Levon

+3

Mach dir keine Sorgen. Dies ist der beabsichtigte Zweck von 'sys.path' (oder mindestens * ein * beabsichtigter Anwendungsfall). Herr F (der anscheinend vorher EMS war) liegt falsch. Wie phihag in seiner Antwort auf den identischen -1 Kommentar zu seiner Antwort feststellt, ist "sys.path" * nicht * mit dem Gesamtsystempfad verbunden. –

1

Nach phihag Tipp, ich diese Lösung haben. Gib einfach den Pfad einer Quelldatei zu load_src und es wird es laden. Sie müssen auch einen Namen angeben, damit Sie dieses Modul mit diesem Namen importieren können. Ich ziehe es auf diese Art und Weise zu tun, weil es noch deutlicher:

def load_src(name, fpath): 
    import os, imp 
    return imp.load_source(name, os.path.join(os.path.dirname(__file__), fpath)) 

load_src("util", "../util.py") 
import util 

print util.method() 

Eine andere (weniger explizit) Art und Weise, ist dies:

util = load_src("util", "../util.py") # "import util" is implied here 

print util.method() # works, util was imported by the previous line 

Edit: das Verfahren neu geschrieben wird es deutlicher zu machen.