Ich möchte feststellen, ob sich das Modul geändert hat. Die Verwendung von inotify ist jetzt einfach. Sie müssen nur noch das Verzeichnis kennen, aus dem Sie Benachrichtigungen erhalten möchten.
Wenn Sie immer noch auf dieser Website suchen, aktualisieren Sie bitte die richtige Antwort darauf . Es ist viel sauberer als die vorgeschlagene Lösung und funktioniert auch in Fällen, in denen __file__es nicht festgelegt ist.
Erikbwork
3
@ erikb85: es ist nicht nur sauberer; inspect-basierte Lösung funktioniert auch für den execfile()Fall, dass im __file__Stillen ein falscher Name erzeugt wird.
Hier erfahren Sie, wie Sie den Pfad des zu importierenden Moduls abrufen, jedoch nicht des Moduls / Skripts, in dem Sie sich befinden (für das Skript, das Sie ausführen, __file__handelt es sich nicht um einen vollständigen Pfad, sondern um einen relativen Pfad). 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
5
@hbdgaf ziemlich sicher, dass es keinen eingebauten gibtself.__file__
Dan Passaro
26
@BenBryant @hbdgaf os.path.dirname(__file__)funktioniert gut für mich und gibt den abs-Pfad des Modulverzeichnisses zurück.
Niccolò
9
Ich habe versucht, dies zu tun und die Rückverfolgung zu erhalten: AttributeError: 'module' object has no attribute '__file__'
Dorian Dore
5
@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 Python-Versionen unterscheidet. Es funktioniert für mich, im Gegensatz zu dieser Antwort, die mir den gleichen Fehler gibt und die inspectAntwort erhöht TypeError: <module 'module' (namespace)> is a built-in module...
Das Inspect-Modul bietet verschiedene nützliche Funktionen, um Informationen zu Live-Objekten wie Modulen, Klassen, Methoden, Funktionen, Tracebacks, Frame-Objekten und Code-Objekten abzurufen. Sie können beispielsweise den Inhalt einer Klasse untersuchen, den Quellcode einer Methode abrufen, die Argumentliste für eine Funktion extrahieren und formatieren oder alle Informationen abrufen, die Sie zum Anzeigen 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'
Ich habe diese Frage viele Male gegoogelt und dies ist die vernünftigste Antwort, die ich je gesehen habe! Bitte aktualisieren Sie die Informationen überinspect.currentframe()
erikbwork
Der inspect.getfile()Ansatz funktioniert nicht mit dem Modul _io, sondern mit dem Modul io.
Smwikipedia
70
Wie die anderen Antworten bereits sagten, ist der beste Weg, dies zu tun, mit __file__(unten noch einmal gezeigt). Es gibt jedoch eine wichtige Einschränkung, die __file__NICHT besteht, wenn Sie das Modul alleine ausführen (dh als__main__ ).
Angenommen, Sie haben zwei Dateien (beide befinden sich auf Ihrem PYTHONPATH):
#/path1/foo.pyimport bar
print(bar.__file__)
und
#/path2/bar.pyimport os
print(os.getcwd())print(__file__)
Wenn Sie foo.py ausführen, erhalten Sie folgende 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:
/path2 # "print(os.getcwd())" still works fineTraceback(most recent call last):# but __file__ doesn't exist if bar.py is running as mainFile"/path2/bar.py", line 3,in<module>print(__file__)NameError: name '__file__'isnot defined
Hoffe das hilft. Diese Einschränkung hat mich beim Testen der anderen vorgestellten Lösungen viel Zeit und Verwirrung gekostet.
In diesem Fall können Sie anstelle der Datei sys.argv [0] verwenden .
Jimothy
4
Ist das eine versionenspezifische Einschränkung? In 2.6 und 2.7 verlasse ich mich erfolgreich auf Datei , die Datei funktioniert, wenn Name __ == '__ main '. Der einzige Fehlerfall, den ich gesehen habe, ist "python -c 'print file '". Ich werde hinzufügen, dass die Datei manchmal '<stdin>' sein kann, was passiert, wenn IDEs wie Emacs den aktuellen Puffer ausführen.
Paul Du Bois
1
Beachten Sie, dass führende und nachfolgende "__" -Zeichen ein Wort in Fettdruck setzen. Denken Sie also daran, wenn Sie die vorherigen Kommentare lesen :-P
Paul Du Bois
1
@PaulDuBois Sie können es mit Back-Tics umgeben: ` __file__` wird__file__
fncomp
1
Wie bekommst du das NameError? @ Paul Du Bois: Ich habe Python versucht 2,3-3,4 und __file__ist definiert aber ich Python - Datei ausführen: python a.py, python -ma, ./a.py.
JFS
43
Ich werde auch versuchen, einige Variationen dieser Frage anzugehen:
Finden des Pfades des aufgerufenen Skripts
Suchen des Pfads des aktuell ausgeführten Skripts
Suchen des Verzeichnisses des aufgerufenen Skripts
(Einige dieser Fragen wurden auf SO gestellt, aber als Duplikate geschlossen und hier umgeleitet.)
Vorsichtsmaßnahmen bei der Verwendung __file__
Für ein Modul, das Sie importiert haben:
import something
something.__file__
gibt den absoluten Pfad des Moduls zurück. Angesichts des folgenden Skripts foo.py:
#foo.pyprint'__file__', __file__
Wenn Sie es mit 'python foo.py' aufrufen, wird einfach 'foo.py' zurückgegeben. Wenn Sie einen Schebang hinzufügen:
und rufen Sie es mit ./foo.py auf, es wird './foo.py' zurückgeben. Rufen Sie es aus einem anderen Verzeichnis auf (z. B. foo.py in die Verzeichnisleiste einfügen) und rufen Sie dann eines der beiden auf
python bar/foo.py
oder einen Shebang hinzufügen und die Datei direkt ausführen:
bar/foo.py
gibt 'bar / foo.py' (den relativen Pfad) zurück.
Das Verzeichnis finden
Jetzt von dort aus das Verzeichnis zu bekommen, os.path.dirname(__file__)kann auch schwierig sein. Zumindest auf meinem System wird eine leere Zeichenfolge zurückgegeben, wenn Sie sie aus demselben Verzeichnis wie die Datei aufrufen. Ex.
# foo.pyimport 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 Zeichenfolge zurückgegeben, sodass dies nicht zuverlässig erscheint, wenn Sie es für die aktuelle Datei verwenden möchten (im Gegensatz zur Datei eines importierten Moduls). Um dies zu umgehen, können Sie es in einen Aufruf an abspath einwickeln:
# foo.pyimport 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__))
Beachten Sie, dass abspath () Symlinks NICHT auflöst. Wenn Sie dies tun möchten, verwenden Sie stattdessen realpath (). Erstellen Sie beispielsweise einen Symlink file_import_testing_link, der auf file_import_testing.py verweist, mit dem folgenden 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:
@SummerBreeze erwähnt die Verwendung der Inspektion Modul.
Dies scheint für importierte Module gut zu funktionieren und ist recht 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, habe ich jedoch keine Möglichkeit gefunden, es zu verwenden.
inspect.getfile (os) ist dasselbe wie os .__ file__ aus dem Code: def getfile (object): "" Ermitteln Sie, in welcher Quell- oder kompilierten Datei ein Objekt definiert wurde. "" if ismodule (object): if hasattr (Objekt, ' Datei '): Objekt zurückgeben .__ Datei__
idanzalz
4
Sie können verwenden inspect.getfile(inspect.currentframe()), um den Pfad des aktuell ausgeführten Skripts abzurufen.
Jbochi
33
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) hier ):
import imp
imp.find_module("os")
Es gibt 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 können eine Zeichenfolge für die Eingabe verwenden. Nützlich, wenn Sie beispielsweise Module überprüfen, die in einem anderen Skript aufgerufen wurden.
BEARBEITEN :
In Python3 importlib Modul tun:
Doc von importlib.util.find_spec :
Geben Sie die Spezifikation für das angegebene Modul zurück.
Zunächst wird sys.modules überprüft, ob das Modul bereits importiert wurde. Wenn ja, dann sys.modules [Name]. spez wird zurückgegeben. Wenn dies zufällig auf Keine gesetzt ist, wird ValueError ausgelöst. Befindet sich das Modul nicht in sys.modules, wird sys.meta_path nach einer geeigneten Spezifikation mit dem Wert 'path' durchsucht, der den Findern zugewiesen wurde. Keine wird zurückgegeben, wenn keine Spezifikation gefunden werden konnte.
Wenn der Name für das Submodul steht (einen Punkt enthält), wird 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.
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)
mdew
Und WIRKLICH schön, wenn versucht wird, den Pfad von 64-Bit-SQLite3 zu finden, und der Import fehlschlägt. Perfekt.
rahvin_t
2
importlib.machinery.PathFinder().find_module("os").get_filename()Die kürzeste Alternative zu imp.find_modulePython3 +. Wenn jemand nach der Verwendung von sucht importlib.util.find_spec.
Torxed
Diese Methode funktioniert ohne den Import des eigentlichen Moduls. Das ist großartig, da ich damit herausfinde, welche Version eines Moduls von einem gemeinsam genutzten Computer importiert wird.
Gouda
19
Das war trivial.
Jedes Modul hat eine __file__ Variable, die den relativen Pfad anzeigt, von dem aus Sie sich gerade befinden.
Daher ist es einfach, ein Verzeichnis für das Modul zu erhalten, um es zu benachrichtigen:
Fast, aber nicht ganz richtig - die Datei ist nicht "relativ zu dem, wo Sie sich gerade befinden"; Wenn es relativ ist (was nur der Fall ist, wenn es in sys.path relative Pfade gibt), ist es relativ zu dem Ort, an dem Sie sich befanden, als das Modul geladen wurde .
Charles Duffy
17
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
funktioniert unter meinem Linux-Python 2.6 nicht, da __file__es sich nur um dir / test.py handelt. Abspath bezieht den cwd ein, um den Pfadnamen zu vervollständigen, der nicht das gewünschte Ergebnis ist. Wenn Sie jedoch ein Modul importieren, erhalten Sie m.__file__das gewünschte Ergebnis.
Ben Bryant
10
import module
print module.__path__
Pakete unterstützen ein weiteres spezielles Attribut __path__. Dies wird als Liste initialisiert, die den Namen des Verzeichnisses enthält, in dem sich das Paket befindet__init__.py bevor der Code in dieser Datei ausgeführt wird. Diese Variable kann geändert werden. Dies wirkt sich auf zukünftige Suchvorgänge nach Modulen und Unterpaketen aus, die im Paket enthalten sind.
Diese Funktion wird zwar nicht oft benötigt, kann jedoch zum Erweitern der in einem Paket enthaltenen Module verwendet werden.
Daher habe ich ziemlich viel Zeit damit verbracht, dies mit py2exe zu versuchen. Das Problem bestand darin, den Basisordner des Skripts abzurufen, unabhängig davon, ob es als Python-Skript oder als ausführbare py2exe-Datei ausgeführt wurde. Damit es funktioniert, ob es aus dem aktuellen Ordner, einem anderen Ordner oder (dies war der schwierigste) aus dem Systempfad ausgeführt wurde.
Schließlich habe ich diesen Ansatz verwendet und sys.frozen als Indikator für die Ausführung in py2exe verwendet:
import os,sys
if hasattr(sys,'frozen'):# only when running in py2exe this exists
base = sys.prefix
else:# otherwise this is a regular python script
base = os.path.dirname(os.path.realpath(__file__))
Wenn die einzige Einschränkung bei der Verwendung darin __file__besteht, dass das aktuelle relative Verzeichnis leer ist (dh wenn es als Skript aus demselben Verzeichnis ausgeführt wird, in dem sich das Skript befindet), lautet die einfache Lösung:
import os.path
mydir = os.path.dirname(__file__)or'.'
full = os.path.abspath(mydir)print __file__, mydir, full
Und das Ergebnis:
$ python teste.py
teste.py ./home/user/work/teste
Der Trick ist or '.'nach dem dirname()Anruf. Es setzt das Verzeichnis als ., was aktuelles Verzeichnis bedeutet und ein gültiges Verzeichnis für jede pfadbezogene Funktion ist.
Daher ist die Verwendung abspath()nicht wirklich erforderlich. Wenn Sie es trotzdem verwenden, wird der Trick nicht benötigt: abspath()Akzeptiert leere Pfade und interpretiert es ordnungsgemäß als aktuelles Verzeichnis.
Tauschen Sie die Reihenfolge besser aus und verwenden os.path.dirname(os.path.abspath(__file__))Sie sie einfach, da Sie sich dann überhaupt nicht um relative Pfade kümmern müssen. Eine Gelegenheit weniger für Fehler.
Szali
3
Ich möchte mit einem gemeinsamen Szenario (in Python 3) einen Beitrag leisten und einige Ansätze dafür untersuchen.
Die integrierte Funktion open () akzeptiert entweder den relativen oder den absoluten Pfad als erstes Argument. Der relative Pfad wird jedoch als relativ zum aktuellen Arbeitsverzeichnis behandelt. Es wird daher empfohlen, den absoluten Pfad an die Datei zu übergeben.
Wenn Sie eine Skriptdatei mit dem folgenden Code ausführen, kann nicht garantiert werden, dass die example.txtDatei in demselben Verzeichnis erstellt wird, in dem sich die Skriptdatei befindet:
with open('example.txt','w'):pass
Um diesen Code zu reparieren, müssen wir den Pfad zum Skript ermitteln und absolut machen. Um sicherzustellen, dass der Pfad absolut ist, verwenden wir einfach die Funktion os.path.realpath () . Um den Pfad zum Skript abzurufen, gibt es mehrere allgemeine Funktionen, die verschiedene Pfadergebnisse zurückgeben:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
Beide Funktionen os.getcwd () und os.path.realpath () geben Pfadergebnisse basierend auf dem aktuellen Arbeitsverzeichnis zurück . Im Allgemeinen nicht das, was wir wollen. Das erste Element der Liste sys.argv ist der Pfad des Stammskripts (des von Ihnen ausgeführten Skripts), unabhängig davon, ob Sie die Liste im Stammskript selbst oder in einem seiner Module aufrufen. In einigen Situationen kann dies hilfreich sein. Die Variable __file__ enthält den Pfad des Moduls, von dem aus sie aufgerufen wurde.
Der folgende Code erstellt eine Datei korrekt example.txtin demselben Verzeichnis, in dem sich das Skript befindet:
Also musste ich oben maincli.py aus dem Modul my_lib_a.py aufrufen, da ich wusste, dass sich top_package und maincli.py im selben Verzeichnis befinden. So erhalte ich den Pfad zu maincli.py:
import sys
import os
import imp
classConfigurationException(Exception):pass# inside of my_lib_a.pydef get_maincli_path():
maincli_path = os.path.abspath(imp.find_module('maincli')[1])# top_package = __package__.split('.')[0]# mod = sys.modules.get(top_package)# modfile = mod.__file__# pkg_in_dir = os.path.dirname(os.path.dirname(os.path.abspath(modfile)))# maincli_path = os.path.join(pkg_in_dir, 'maincli.py')ifnot os.path.exists(maincli_path):
err_msg ='This script expects that "maincli.py" be installed to the '\
'same directory: "{0}"'.format(maincli_path)raiseConfigurationException(err_msg)return maincli_path
Basierend auf der Veröffentlichung von PlasmaBinturong habe ich den Code geändert.
Wenn Sie dies dynamisch in einem "Programm" tun möchten, versuchen Sie diesen Code:
Mein Punkt ist, dass Sie möglicherweise nicht den genauen Namen des Moduls kennen, um es "fest zu codieren". Es kann aus einer Liste ausgewählt werden oder wird derzeit nicht ausgeführt, um __file__ zu verwenden.
(Ich weiß, es wird in Python 3 nicht funktionieren)
global modpath
modname ='os'#This can be any module name on the fly#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()#Call the file with execfile()
execfile('modname.py')print modpath
<module 'os'from'C:\Python27\lib\os.pyc'>
Ich habe versucht, das "globale" Problem zu beseitigen, aber Fälle gefunden, in denen es nicht funktioniert hat. Ich denke, "execfile ()" kann in Python 3 emuliert werden. Da dies in einem Programm enthalten ist, kann es leicht in eine Methode oder ein Modul für eingefügt werden Wiederverwendung.
Hier ist ein kurzes Bash-Skript für den Fall, dass es für irgendjemanden nützlich ist. Ich möchte nur in der Lage sein, eine Umgebungsvariable festzulegen, damit ich pushdauf den Code zugreifen kann .
#!/bin/bash
module=${1:?"I need a module name"}
python << EOI
import $module
import os
print os.path.dirname($module.__file__)
EOI
__file__
es nicht festgelegt ist.inspect
-basierte Lösung funktioniert auch für denexecfile()
Fall, dass im__file__
Stillen ein falscher Name erzeugt wird.import pathlib, module; pathlib.Path(module.__file__).resolve().parent
Dies ist plattformunabhängigAntworten:
Gibt Ihnen tatsächlich den Pfad zu der .pyc-Datei, die geladen wurde, zumindest unter Mac OS X. Sie können also Folgendes tun:
Sie können auch versuchen:
Um das Verzeichnis des Moduls abzurufen.
quelle
__file__
handelt es sich nicht um einen vollständigen Pfad, sondern um einen relativen Pfad). 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?self.__file__
os.path.dirname(__file__)
funktioniert gut für mich und gibt den abs-Pfad des Modulverzeichnisses zurück.AttributeError: 'module' object has no attribute '__file__'
path = module.__path__.__dict__["_path"][0]
, aber ich bin mir nicht sicher, ob es portabel ist oder ob es sich auch nicht zwischen Python-Versionen unterscheidet. Es funktioniert für mich, im Gegensatz zu dieser Antwort, die mir den gleichen Fehler gibt und dieinspect
Antwort erhöhtTypeError: <module 'module' (namespace)> is a built-in module
...Es gibt ein
inspect
Modul in Python.Offizielle Dokumentation
Beispiel:
quelle
inspect
den Namen der aktuellen Datei abrufen. siehe stackoverflow.com/a/50905/320036inspect.currentframe()
inspect.getfile()
Ansatz funktioniert nicht mit dem Modul_io
, sondern mit dem Modulio
.Wie die anderen Antworten bereits sagten, ist der beste Weg, dies zu tun, mit
__file__
(unten noch einmal gezeigt). Es gibt jedoch eine wichtige Einschränkung, die__file__
NICHT besteht, wenn Sie das Modul alleine ausführen (dh als__main__
).Angenommen, Sie haben zwei Dateien (beide befinden sich auf Ihrem PYTHONPATH):
und
Wenn Sie foo.py ausführen, erhalten Sie folgende Ausgabe:
Wenn Sie jedoch versuchen, bar.py alleine auszuführen, erhalten Sie:
Hoffe das hilft. Diese Einschränkung hat mich beim Testen der anderen vorgestellten Lösungen viel Zeit und Verwirrung gekostet.
quelle
__file__
` wird__file__
NameError
? @ Paul Du Bois: Ich habe Python versucht 2,3-3,4 und__file__
ist definiert aber ich Python - Datei ausführen:python a.py
,python -ma
,./a.py
.Ich werde auch versuchen, einige Variationen dieser Frage anzugehen:
(Einige dieser Fragen wurden auf SO gestellt, aber als Duplikate geschlossen und hier umgeleitet.)
Vorsichtsmaßnahmen bei der Verwendung
__file__
Für ein Modul, das Sie importiert haben:
gibt den absoluten Pfad des Moduls zurück. Angesichts des folgenden Skripts foo.py:
Wenn Sie es mit 'python foo.py' aufrufen, wird einfach 'foo.py' zurückgegeben. Wenn Sie einen Schebang hinzufügen:
und rufen Sie es mit ./foo.py auf, es wird './foo.py' zurückgeben. Rufen Sie es aus einem anderen Verzeichnis auf (z. B. foo.py in die Verzeichnisleiste einfügen) und rufen Sie dann eines der beiden auf
oder einen Shebang hinzufügen und die Datei direkt ausführen:
gibt 'bar / foo.py' (den relativen Pfad) zurück.
Das Verzeichnis finden
Jetzt von dort aus das Verzeichnis zu bekommen,
os.path.dirname(__file__)
kann auch schwierig sein. Zumindest auf meinem System wird eine leere Zeichenfolge zurückgegeben, wenn Sie sie aus demselben Verzeichnis wie die Datei aufrufen. Ex.wird ausgegeben:
Mit anderen Worten, es wird eine leere Zeichenfolge zurückgegeben, sodass dies nicht zuverlässig erscheint, wenn Sie es für die aktuelle Datei verwenden möchten (im Gegensatz zur Datei eines importierten Moduls). Um dies zu umgehen, können Sie es in einen Aufruf an abspath einwickeln:
welches etwas ausgibt wie:
Beachten Sie, dass abspath () Symlinks NICHT auflöst. Wenn Sie dies tun möchten, verwenden Sie stattdessen realpath (). Erstellen Sie beispielsweise einen Symlink file_import_testing_link, der auf file_import_testing.py verweist, mit dem folgenden Inhalt:
Beim Ausführen werden absolute Pfade wie folgt gedruckt:
file_import_testing_link -> file_import_testing.py
Mit inspizieren
@SummerBreeze erwähnt die Verwendung der Inspektion Modul.
Dies scheint für importierte Module gut zu funktionieren und ist recht prägnant:
gibt gehorsam den absoluten Pfad zurück. Um den Pfad des aktuell ausgeführten Skripts zu finden, habe ich jedoch keine Möglichkeit gefunden, es zu verwenden.
quelle
inspect.getfile(inspect.currentframe())
, um den Pfad des aktuell ausgeführten Skripts abzurufen.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) hier ):
Es gibt ein Tupel mit dem Pfad an zweiter Stelle:
Der Vorteil dieser Methode gegenüber der "Inspect" -Methode besteht darin, dass Sie das Modul nicht importieren müssen, damit es funktioniert, und Sie können eine Zeichenfolge für die Eingabe verwenden. Nützlich, wenn Sie beispielsweise Module überprüfen, die in einem anderen Skript aufgerufen wurden.
BEARBEITEN :
In Python3
importlib
Modul tun:Doc von
importlib.util.find_spec
:quelle
importlib.machinery.PathFinder().find_module("os").get_filename()
Die kürzeste Alternative zuimp.find_module
Python3 +. Wenn jemand nach der Verwendung von suchtimportlib.util.find_spec
.Das war trivial.
Jedes Modul hat eine
__file__
Variable, die den relativen Pfad anzeigt, von dem aus Sie sich gerade befinden.Daher ist es einfach, ein Verzeichnis für das Modul zu erhalten, um es zu benachrichtigen:
quelle
quelle
__file__
es sich nur um dir / test.py handelt. Abspath bezieht den cwd ein, um den Pfadnamen zu vervollständigen, der nicht das gewünschte Ergebnis ist. Wenn Sie jedoch ein Modul importieren, erhalten Siem.__file__
das gewünschte Ergebnis.Quelle
quelle
Befehlszeilenprogramm
Sie können es an einem Befehlszeilenprogramm anpassen.
Erstellen
/usr/local/bin/python-which
Mach es ausführbar
quelle
Daher habe ich ziemlich viel Zeit damit verbracht, dies mit py2exe zu versuchen. Das Problem bestand darin, den Basisordner des Skripts abzurufen, unabhängig davon, ob es als Python-Skript oder als ausführbare py2exe-Datei ausgeführt wurde. Damit es funktioniert, ob es aus dem aktuellen Ordner, einem anderen Ordner oder (dies war der schwierigste) aus dem Systempfad ausgeführt wurde.
Schließlich habe ich diesen Ansatz verwendet und sys.frozen als Indikator für die Ausführung in py2exe verwendet:
quelle
Sie können Ihr Modul einfach importieren und dann auf seinen Namen klicken, um den vollständigen Pfad zu erhalten
quelle
Wenn Sie den Stammpfad des Pakets von einem seiner Module abrufen möchten, funktioniert Folgendes (getestet in Python 3.6):
Der Hauptpfad
__init__.py
kann auch mit referenziert werden__file__
.Hoffe das hilft!
quelle
Wenn die einzige Einschränkung bei der Verwendung darin
__file__
besteht, dass das aktuelle relative Verzeichnis leer ist (dh wenn es als Skript aus demselben Verzeichnis ausgeführt wird, in dem sich das Skript befindet), lautet die einfache Lösung:Und das Ergebnis:
Der Trick ist
or '.'
nach demdirname()
Anruf. Es setzt das Verzeichnis als.
, was aktuelles Verzeichnis bedeutet und ein gültiges Verzeichnis für jede pfadbezogene Funktion ist.Daher ist die Verwendung
abspath()
nicht wirklich erforderlich. Wenn Sie es trotzdem verwenden, wird der Trick nicht benötigt:abspath()
Akzeptiert leere Pfade und interpretiert es ordnungsgemäß als aktuelles Verzeichnis.quelle
os.path.dirname(os.path.abspath(__file__))
Sie sie einfach, da Sie sich dann überhaupt nicht um relative Pfade kümmern müssen. Eine Gelegenheit weniger für Fehler.Ich möchte mit einem gemeinsamen Szenario (in Python 3) einen Beitrag leisten und einige Ansätze dafür untersuchen.
Die integrierte Funktion open () akzeptiert entweder den relativen oder den absoluten Pfad als erstes Argument. Der relative Pfad wird jedoch als relativ zum aktuellen Arbeitsverzeichnis behandelt. Es wird daher empfohlen, den absoluten Pfad an die Datei zu übergeben.
Wenn Sie eine Skriptdatei mit dem folgenden Code ausführen, kann nicht garantiert werden, dass die
example.txt
Datei in demselben Verzeichnis erstellt wird, in dem sich die Skriptdatei befindet:Um diesen Code zu reparieren, müssen wir den Pfad zum Skript ermitteln und absolut machen. Um sicherzustellen, dass der Pfad absolut ist, verwenden wir einfach die Funktion os.path.realpath () . Um den Pfad zum Skript abzurufen, gibt es mehrere allgemeine Funktionen, die verschiedene Pfadergebnisse zurückgeben:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
Beide Funktionen os.getcwd () und os.path.realpath () geben Pfadergebnisse basierend auf dem aktuellen Arbeitsverzeichnis zurück . Im Allgemeinen nicht das, was wir wollen. Das erste Element der Liste sys.argv ist der Pfad des Stammskripts (des von Ihnen ausgeführten Skripts), unabhängig davon, ob Sie die Liste im Stammskript selbst oder in einem seiner Module aufrufen. In einigen Situationen kann dies hilfreich sein. Die Variable __file__ enthält den Pfad des Moduls, von dem aus sie aufgerufen wurde.
Der folgende Code erstellt eine Datei korrekt
example.txt
in demselben Verzeichnis, in dem sich das Skript befindet:quelle
Wenn Sie den absoluten Pfad aus Ihrem Skript kennen möchten, können Sie das Path- Objekt verwenden:
cwd () -Methode
Lösung () Methode
quelle
Innerhalb der Module eines Python-Pakets musste ich auf eine Datei verweisen, die sich im selben Verzeichnis wie das Paket befand. Ex.
Also musste ich oben maincli.py aus dem Modul my_lib_a.py aufrufen, da ich wusste, dass sich top_package und maincli.py im selben Verzeichnis befinden. So erhalte ich den Pfad zu maincli.py:
Basierend auf der Veröffentlichung von PlasmaBinturong habe ich den Code geändert.
quelle
Wenn Sie dies dynamisch in einem "Programm" tun möchten, versuchen Sie diesen Code:
Mein Punkt ist, dass Sie möglicherweise nicht den genauen Namen des Moduls kennen, um es "fest zu codieren". Es kann aus einer Liste ausgewählt werden oder wird derzeit nicht ausgeführt, um __file__ zu verwenden.
(Ich weiß, es wird in Python 3 nicht funktionieren)
Ich habe versucht, das "globale" Problem zu beseitigen, aber Fälle gefunden, in denen es nicht funktioniert hat. Ich denke, "execfile ()" kann in Python 3 emuliert werden. Da dies in einem Programm enthalten ist, kann es leicht in eine Methode oder ein Modul für eingefügt werden Wiederverwendung.
quelle
Wenn Sie es mit pip installiert haben, funktioniert "pip show" hervorragend ('Location')
$ pip show detektron2
quelle
Hier ist ein kurzes Bash-Skript für den Fall, dass es für irgendjemanden nützlich ist. Ich möchte nur in der Lage sein, eine Umgebungsvariable festzulegen, damit ich
pushd
auf den Code zugreifen kann .Shell-Beispiel:
quelle