Wie kann ich den Pfad eines Moduls abrufen?

Lesezeit: 11 Minuten

Benutzer-Avatar
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?

  • 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ür execfile() 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


Benutzer-Avatar
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.

Offizielle Dokumentation

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 _iofunktioniert aber mit dem Modul io.

    – smWikipedia

    6. Oktober 2014 um 1:28 Uhr

Benutzer-Avatar
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 ‘‘ ​​sein, was passiert, wenn IDEs wie emacs den aktuellen Puffer ausführen.

    – 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

Benutzer-Avatar
jpgeek

Ich werde versuchen, auch einige Variationen dieser Frage anzugehen:

  1. Finden des Pfades des aufgerufenen Skripts
  2. Ermitteln des Pfads des aktuell ausgeführten Skripts
  3. Finden des Verzeichnisses des aufgerufenen Skripts

(Einige dieser Fragen wurden auf SO gestellt, aber als Duplikate geschlossen und hierher umgeleitet.)

Vorbehalte bei der Verwendung __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).

Suche nach dem Verzeichnis

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

Inspizieren verwenden

@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).

Benutzer-Avatar
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


Benutzer-Avatar
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


Benutzer-Avatar
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


1145200cookie-checkWie kann ich den Pfad eines Moduls abrufen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy