Ich möchte feststellen, ob sich das Modul geändert hat. Die Verwendung von inotify ist einfach, Sie müssen nur das Verzeichnis kennen, von dem Sie Benachrichtigungen erhalten möchten.
Wie kann ich den Pfad eines Moduls in Python abrufen?
Ich möchte feststellen, ob sich das Modul geändert hat. Die Verwendung von inotify ist einfach, Sie müssen nur das Verzeichnis kennen, von dem Sie Benachrichtigungen erhalten möchten.
Wie kann ich den Pfad eines Moduls in Python abrufen?
import a_module
print(a_module.__file__)
gibt Ihnen den Pfad zu der geladenen .pyc-Datei an, zumindest unter Mac OS X. Ich denke also, dass Sie das tun können:
import os
path = os.path.abspath(a_module.__file__)
Sie können auch versuchen:
path = os.path.dirname(a_module.__file__)
Um das Verzeichnis des Moduls zu erhalten.
Es gibt inspect
Modul in Python.
Das Modul inspect bietet mehrere nützliche Funktionen, um Informationen über Live-Objekte wie Module, Klassen, Methoden, Funktionen, Tracebacks, Frame-Objekte und Code-Objekte. Zum Beispiel, kann es Ihnen helfen, den Inhalt einer Klasse zu untersuchen, den Quellcode einer Methode abzurufen Quellcode einer Methode abrufen, die Argumentliste einer Funktion extrahieren und formatieren, oder Sie erhalten alle Informationen, die Sie zur Anzeige eines detaillierten Tracebacks benötigen.
Beispiel:
>>> import os
>>> import inspect
>>> inspect.getfile(os)
'/usr/lib64/python2.7/os.pyc'
>>> inspect.getfile(inspect)
'/usr/lib64/python2.7/inspect.pyc'
>>> os.path.dirname(inspect.getfile(inspect))
'/usr/lib64/python2.7'
Wie bereits in den anderen Antworten erwähnt, ist es am besten, dies mit __file__
(unten noch einmal demonstriert). Es gibt jedoch einen wichtigen Vorbehalt, nämlich den, dass __file__
existiert NICHT, wenn Sie das Modul eigenständig ausführen (d. h. als __main__
).
Nehmen wir zum Beispiel an, Sie haben zwei Dateien (die beide in Ihrem PYTHONPATH liegen):
#/path1/foo.py
import bar
print(bar.__file__)
y
#/path2/bar.py
import os
print(os.getcwd())
print(__file__)
Wenn Sie foo.py ausführen, erhalten Sie diese Ausgabe:
/path1 # "import bar" causes the line "print(os.getcwd())" to run
/path2/bar.py # then "print(__file__)" runs
/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs
JEDOCH, wenn Sie versuchen, bar.py allein auszuführen, erhalten Sie:
/path2 # "print(os.getcwd())" still works fine
Traceback (most recent call last): # but __file__ doesn't exist if bar.py is running as main
File "/path2/bar.py", line 3, in <module>
print(__file__)
NameError: name '__file__' is not defined
Ich hoffe, das hilft. Diese Warnung kostete mich viel Zeit und Verwirrung beim Testen der anderen vorgestellten Lösungen.
Ich werde versuchen, auch diese Frage in einigen Variationen zu behandeln:
(Einige dieser Fragen wurden bereits auf SO gestellt, wurden aber als Duplikate geschlossen und hierher weitergeleitet).
__file__
Für ein Modul, das Sie importiert haben:
import something
something.__file__
gibt die absolut Pfad des Moduls. Bei folgendem Skript foo.py:
#foo.py
print '__file__', __file__
Ein Aufruf mit 'python foo.py' gibt einfach 'foo.py' zurück. Wenn Sie einen Shebang hinzufügen:
#!/usr/bin/python
#foo.py
print '__file__', __file__
und rufen Sie es mit ./foo.py auf, wird es './foo.py' zurückgeben. Ruft man es aus einem anderen Verzeichnis auf (z.B. foo.py im Verzeichnis bar), dann ruft man entweder
python bar/foo.py
oder einen Shebang hinzufügen und die Datei direkt ausführen:
bar/foo.py
wird 'bar/foo.py' zurückgeben (die relativ Pfad).
Von dort aus können Sie nun das Verzeichnis abrufen, os.path.dirname(__file__)
kann auch knifflig sein. Zumindest auf meinem System gibt es eine leere Zeichenfolge zurück, wenn Sie es aus dem gleichen Verzeichnis wie die Datei aufrufen.
# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)
wird ausgegeben:
__file__ is: foo.py
os.path.dirname(__file__) is:
Mit anderen Worten, es wird eine leere Zeichenkette zurückgegeben, so dass dies nicht zuverlässig erscheint, wenn Sie es für die aktuelle Datei (im Gegensatz zu den Datei eines importierten Moduls). Um dies zu umgehen, können Sie es in einen Aufruf von abspath verpacken:
# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))
die etwas wie ausgibt:
os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar
Beachten Sie, dass abspath() Symlinks NICHT auflöst. Wenn Sie dies tun wollen, verwenden Sie stattdessen realpath(). Beispiel: Erstellen Sie einen Symlink file_import_testing_link, der auf file_import_testing.py zeigt, mit dem folgenden Inhalt:
import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)
ausführt, werden absolute Pfade etwa so ausgegeben:
abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py
file_import_testing_link -> file_import_testing.py
@SummerBreeze erwähnt die Verwendung des prüfen Modul.
Dies scheint gut zu funktionieren und ist bei importierten Modulen recht übersichtlich:
import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)
gibt gehorsamst den absoluten Pfad zurück. Zum Auffinden des Pfads des aktuell ausgeführten Skripts:
inspect.getfile(inspect.currentframe())
(danke @jbochi)
inspect.getabsfile(inspect.currentframe())
gibt den absoluten Pfad des aktuell ausgeführten Skripts an (danke @Sadman_Sakib).
Ich verstehe nicht, warum niemand darüber spricht, aber für mich ist die einfachste Lösung die Verwendung von imp.find_module("modulname") (Dokumentation aquí ) :
import imp
imp.find_module("os")
Es ergibt ein Tupel mit dem Pfad an zweiter Stelle:
(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,
'/usr/lib/python2.7/os.py',
('.py', 'U', 1))
Der Vorteil dieser Methode gegenüber der "inspect"-Methode ist, dass man das Modul nicht importieren muss, damit sie funktioniert, und dass man einen String als Eingabe verwenden kann. Nützlich z.B. bei der Überprüfung von Modulen, die in einem anderen Skript aufgerufen werden.
EDIT :
In python3, importlib
Modul tun sollte:
Dokument von importlib.util.find_spec
:
Gibt die Spezifikation für das angegebene Modul zurück.
Zunächst wird in sys.modules geprüft, ob das Modul bereits importiert wurde. Wenn ja, dann wird sys.modules[name]. spec zurückgegeben wird. Wenn dieser zufällig auf auf None gesetzt, dann wird ValueError ausgelöst. Wenn sich das Modul nicht in sys.modules, dann wird sys.meta_path nach einer geeigneten Spezifikation mit dem Wert von 'path' an die Finder übergeben. Keine wird zurückgegeben, wenn keine Spezifikation gefunden wird.
Wenn der Name für ein Submodul steht (einen Punkt enthält), ist das übergeordnete Modul automatisch importiert.
Die Argumente name und package funktionieren genauso wie importlib.import_module(). Mit anderen Worten: relative Modulnamen (mit führenden Punkten) funktionieren.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.