Ich möchte feststellen, ob sich das Modul geändert hat. Jetzt ist die Verwendung von inotify einfach, Sie müssen nur das Verzeichnis kennen, von dem Sie Benachrichtigungen erhalten möchten.
Wie rufe ich den Pfad eines Moduls in Python ab?
Heiter
Ich möchte feststellen, ob sich das Modul geändert hat. Jetzt ist die Verwendung von inotify einfach, Sie müssen nur das Verzeichnis kennen, von dem Sie Benachrichtigungen erhalten möchten.
Wie rufe ich den Pfad eines Moduls in Python ab?
orestis
import a_module
print(a_module.__file__)
Gibt Ihnen tatsächlich den Pfad zu der geladenen .pyc-Datei, zumindest unter Mac OS X. Ich denke, Sie können Folgendes tun:
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.
Dies beantwortet, wie Sie den Pfad des Moduls erhalten, das Sie importieren, aber nicht des Moduls / Skripts, in dem Sie sich befinden (für das Skript, das Sie ausführen, __file__
ist kein vollständiger Pfad, sondern relativ). Für die Datei, in der ich mich befinde, musste ich ein anderes Modul aus demselben Verzeichnis importieren und wie hier gezeigt vorgehen. Kennt jemand einen bequemeren Weg?
– Ben Bryant
19. Januar 2012 um 18:11 Uhr
@hbdgaf ziemlich sicher, dass es so etwas wie ein eingebautes nicht gibt self.__file__
– Dan Passaro
5. November 2013 um 21:24 Uhr
@BenBryant @hbdgaf os.path.dirname(__file__)
funktioniert gut für mich und gibt den ABS-Pfad des Modulverzeichnisses zurück.
– Nicolo
18. August 2014 um 16:14 Uhr
Ich habe versucht, dies zu tun und bekomme den Traceback: AttributeError: 'module' object has no attribute '__file__'
– Dorian Dore
5. April 2015 um 17:02 Uhr
@DorianDore Ich habe ein wenig mit Modulen herumgespielt und bin zu einer Lösung gekommen path = module.__path__.__dict__["_path"][0]
, aber ich bin mir nicht sicher, ob es portabel ist oder ob es sich auch nicht zwischen den Python-Versionen unterscheidet. Es funktioniert für mich, im Gegensatz zu dieser Antwort, die mir den gleichen Fehler gibt und inspect
Antwort erhöht TypeError: <module 'module' (namespace)> is a built-in module
…
– Jesor
4. Juli 2016 um 0:15 Uhr
Es gibt inspect
Modul in Python.
Das Inspect-Modul bietet mehrere nützliche Funktionen, um Informationen über Live-Objekte wie Module, Klassen, Methoden, Funktionen, Tracebacks, Frame-Objekte und Code-Objekte zu erhalten. Beispielsweise kann es Ihnen helfen, den Inhalt einer Klasse zu untersuchen, den Quellcode einer Methode abzurufen, die Argumentliste für eine Funktion zu extrahieren und zu formatieren oder alle Informationen zu erhalten, die Sie zum Anzeigen einer detaillierten Rückverfolgung 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'
Sie können verwenden inspect
um auch den Namen der aktuellen Datei zu erhalten; siehe stackoverflow.com/a/50905/320036
– z0r
24. September 2013 um 4:57 Uhr
Ich habe diese Frage viele Male gegoogelt und Dies ist die vernünftigste Antwort, die ich je gesehen habe! Bitte aktualisieren Sie die Informationen über inspect.currentframe()
– erikbstack
18. Dezember 2013 um 11:15 Uhr
das inspect.getfile()
Ansatz funktioniert nicht mit dem Modul _io
funktioniert aber mit dem Modul io
.
– smWikipedia
6. Oktober 2014 um 1:28 Uhr
Mcstrother
Wie die anderen Antworten gesagt haben, ist dies am besten mit __file__
(unten noch einmal demonstriert). Es gibt jedoch eine wichtige Einschränkung, nämlich die __file__
existiert NICHT, wenn Sie das Modul alleine ausführen (d. h. als __main__
).
Angenommen, Sie haben zwei Dateien (beide befinden sich auf Ihrem PYTHONPATH):
#/path1/foo.py
import bar
print(bar.__file__)
und
#/path2/bar.py
import os
print(os.getcwd())
print(__file__)
Wenn Sie foo.py ausführen, erhalten Sie die 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
Wenn Sie jedoch versuchen, bar.py alleine auszuführen, erhalten Sie Folgendes:
/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
Hoffe das hilft. Dieser Vorbehalt hat mich beim Testen der anderen vorgestellten Lösungen viel Zeit und Verwirrung gekostet.
In diesem Fall können Sie sys.argv verwenden[0] anstelle von Datei.
– Jimothy
14. Februar 2013 um 17:41 Uhr
Ist das ein versionsspezifischer Vorbehalt? Auf 2.6 und 2.7 verlasse ich mich erfolgreich Dateiwelche Datei funktioniert, wenn name__==’__main‘. Der einzige Fehlerfall, den ich gesehen habe, ist mit “python -c ‘print Datei‘”. Ich werde das manchmal hinzufügen Datei kann ‘
– Paul du Bois
19. Februar 2013 um 21:23 Uhr
Beachten Sie, dass führende und abschließende „__“-Zeichen ein Wort fett darstellen, also denken Sie daran, wenn Sie die vorherigen Kommentare lesen 😛
– Paul du Bois
19. Februar 2013 um 21:24 Uhr
@PaulDuBois Sie können es mit Rücken-Ticks umgeben: `__file__
` wird __file__
– fncomp
30. März 2013 um 20:30 Uhr
Wie bekommt man die NameError
? @Paul Du Bois: Ich habe Python 2.3-3.4 ausprobiert und __file__
ist definiert, aber ich führe die Python-Datei aus: python a.py
, python -ma
, ./a.py
.
– jfs
21. Februar 2014 um 13:37 Uhr
jpgeek
Ich werde versuchen, auch einige Variationen dieser Frage anzugehen:
(Einige dieser Fragen wurden auf SO gestellt, aber als Duplikate geschlossen und hierher umgeleitet.)
__file__
Für ein Modul, das Sie importiert haben:
import something
something.__file__
werde die zurückgeben absolut Pfad des Moduls. Angesichts des folgenden Skripts foo.py:
#foo.py
print '__file__', __file__
Wenn Sie es mit „python foo.py“ aufrufen, wird einfach „foo.py“ zurückgegeben. Wenn Sie einen Shebang hinzufügen:
#!/usr/bin/python
#foo.py
print '__file__', __file__
und rufen Sie es mit ./foo.py auf, es wird ‘./foo.py’ zurückgegeben. Rufen Sie es aus einem anderen Verzeichnis auf (z. B. legen Sie foo.py in die Verzeichnisleiste), und rufen Sie dann eines von beiden auf
python bar/foo.py
oder einen Shebang hinzufügen und die Datei direkt ausführen:
bar/foo.py
gibt ‘bar/foo.py’ zurück (die relativ Weg).
Gehen Sie jetzt von dort aus, um das Verzeichnis zu erhalten, os.path.dirname(__file__)
kann auch knifflig sein. Zumindest auf meinem System gibt es eine leere Zeichenfolge zurück, wenn Sie es aus demselben Verzeichnis wie die Datei aufrufen. ex.
# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)
wird ausgeben:
__file__ is: foo.py
os.path.dirname(__file__) is:
Mit anderen Worten, es gibt eine leere Zeichenfolge zurück, sodass dies nicht zuverlässig erscheint, wenn Sie es für den Strom verwenden möchten Datei (im Gegensatz zu den Datei eines importierten Moduls). Um dies zu umgehen, können Sie es in einen Aufruf von abspath packen:
# 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__))
was so etwas ausgibt wie:
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 möchten, verwenden Sie stattdessen realpath(). Erstellen Sie beispielsweise einen symbolischen Link file_import_testing_link, der auf file_import_testing.py verweist, mit folgendem Inhalt:
import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)
Beim Ausführen werden absolute Pfade wie folgt gedruckt:
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 von prüfen Modul.
Dies scheint für importierte Module gut zu funktionieren und ist ziemlich prägnant:
import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)
gibt gehorsam den absoluten Pfad zurück. Um den Pfad des aktuell ausgeführten Skripts zu finden:
inspect.getfile(inspect.currentframe())
(Danke @jbochi)
inspect.getabsfile(inspect.currentframe())
gibt den absoluten Pfad des aktuell ausgeführten Skripts an (danke @Sadman_Sakib).
PlasmaBinturong
Ich verstehe nicht, warum niemand darüber spricht, aber für mich ist die einfachste Lösung die Verwendung imp.find_module(“Modulname”) (Dokumentation hier):
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 besteht darin, dass Sie das Modul nicht importieren müssen, damit es funktioniert, und Sie eine Zeichenfolge in der Eingabe verwenden können. Nützlich, wenn Sie beispielsweise Module prüfen, die in einem anderen Skript aufgerufen werden.
BEARBEITEN:
In python3, importlib
Modul sollte tun:
Dok. von importlib.util.find_spec
:
Gibt die Spezifikation für das angegebene Modul zurück.
Zunächst wird in sys.modules überprüft, ob das Modul bereits importiert wurde. Wenn ja, dann sys.modules[name].spez ist zurück gekommen. Wenn dies zufällig auf None gesetzt ist, wird ValueError ausgelöst. Wenn sich das Modul nicht in sys.modules befindet, wird sys.meta_path nach einer geeigneten Spezifikation durchsucht, wobei den Findern der Wert „path“ gegeben wird. None wird zurückgegeben, wenn keine Spezifikation gefunden werden konnte.
Wenn der Name für ein Untermodul steht (einen Punkt enthält), wird das übergeordnete Modul automatisch importiert.
Die Namens- und Paketargumente funktionieren genauso wie importlib.import_module(). Mit anderen Worten, relative Modulnamen (mit führenden Punkten) funktionieren.
imp wird in Python 2 (aktuelle Version 2.7.13) NICHT abgeschrieben. imp wird in Python 3 seit 3.4 abgeschrieben. importlib soll stattdessen in Python 3 verwendet werden. Ich mag diese Lösung, weil sie sogar funktioniert, wenn der eigentliche Import fehlschlägt (z. B. weil 64-Bit-Modul für eine 32-Bit-Engine)
– Tau
21. Dezember 2016 um 7:57 Uhr
Und WIRKLICH schön, wenn Sie versuchen, den Pfad von 64-Bit-sqlite3 zu finden und der Import fehlschlägt. Perfekt.
– rahvin_t
7. Dezember 2018 um 20:49 Uhr
importlib.machinery.PathFinder().find_module("os").get_filename()
Kürzeste Alternative zu imp.find_module
Ich habe in Python3+ gefunden. Wenn jemand nach der Verwendung von sucht importlib.util.find_spec
.
– Torx
24. März 2019 um 16:10 Uhr
Diese Methode funktioniert, ohne das eigentliche Modul zu importieren, was großartig ist, da ich damit herausfinden kann, welche Version eines Moduls von einem gemeinsam genutzten Computer importiert wird.
– Gouda
9. Mai 2019 um 7:07 Uhr
DeprecationWarning: Das imp-Modul ist zugunsten von veraltet importlib
.. und “AttributeError: Modul ‘importlib’ hat kein Attribut ‘find_module'”
– Peter Krauß
2. November 2021 um 13:02 Uhr
Blair Konrad
Das war trivial.
Jedes Modul hat eine __file__
Variable, die den relativen Pfad von Ihrem aktuellen Standort aus anzeigt.
Daher ist es einfach, ein Verzeichnis für das Modul zu erhalten, um es zu benachrichtigen:
os.path.dirname(__file__)
imp wird in Python 2 (aktuelle Version 2.7.13) NICHT abgeschrieben. imp wird in Python 3 seit 3.4 abgeschrieben. importlib soll stattdessen in Python 3 verwendet werden. Ich mag diese Lösung, weil sie sogar funktioniert, wenn der eigentliche Import fehlschlägt (z. B. weil 64-Bit-Modul für eine 32-Bit-Engine)
– Tau
21. Dezember 2016 um 7:57 Uhr
Und WIRKLICH schön, wenn Sie versuchen, den Pfad von 64-Bit-sqlite3 zu finden und der Import fehlschlägt. Perfekt.
– rahvin_t
7. Dezember 2018 um 20:49 Uhr
importlib.machinery.PathFinder().find_module("os").get_filename()
Kürzeste Alternative zu imp.find_module
Ich habe in Python3+ gefunden. Wenn jemand nach der Verwendung von sucht importlib.util.find_spec
.
– Torx
24. März 2019 um 16:10 Uhr
Diese Methode funktioniert, ohne das eigentliche Modul zu importieren, was großartig ist, da ich damit herausfinden kann, welche Version eines Moduls von einem gemeinsam genutzten Computer importiert wird.
– Gouda
9. Mai 2019 um 7:07 Uhr
DeprecationWarning: Das imp-Modul ist zugunsten von veraltet importlib
.. und “AttributeError: Modul ‘importlib’ hat kein Attribut ‘find_module'”
– Peter Krauß
2. November 2021 um 13:02 Uhr
wkl
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
funktioniert seitdem nicht mehr auf meinem Linux Python 2.6 __file__
ist nur dir/test.py, abspath beinhaltet das cwd, um den Pfadnamen zu vervollständigen, was nicht das gewünschte Ergebnis ist, aber wenn Sie dann ein Modul importieren m.__file__
gibt das gewünschte Ergebnis.
– Ben Bryant
19. Januar 2012 um 17:41 Uhr
Schauen Sie sich den Modulfinder an: docs.python.org/library/modulefinder.html
– Benutzer1256374
8. März 2012 um 6:19 Uhr
Wenn Sie immer noch auf dieser Website suchen, aktualisieren Sie bitte die richtige Antwort auf Dies. Es ist viel sauberer als die vorgeschlagene Lösung und funktioniert auch in Fällen, in denen
__file__
ist nicht eingestellt.– erikbstack
18. Dezember 2013 um 11:16 Uhr
@erikb85: es ist nicht nur sauberer;
inspect
-basierte Lösung funktioniert auch fürexecfile()
Fall wann__file__
produziert lautlos falschen Namen.– jfs
21. Februar 2014 um 13:49 Uhr
verwandt: Wie kann man das aktuelle Skriptverzeichnis in Python richtig bestimmen?
– jfs
19. November 2015 um 4:43 Uhr
import pathlib, module; pathlib.Path(module.__file__).resolve().parent
Dies ist plattformunabhängig– MortenB
16. März 2018 um 11:48 Uhr