it-swarm.com.de

Wie bekomme ich den Pfad der aktuell ausgeführten Datei in Python?

Dies mag wie eine Neulingfrage aussehen, ist es aber nicht. Einige gängige Ansätze funktionieren nicht in allen Fällen:

sys.argv [0]

Dies bedeutet, dass path = os.path.abspath(os.path.dirname(sys.argv[0])) verwendet wird. Dies funktioniert jedoch nicht, wenn Sie ein anderes Python-Skript in einem anderen Verzeichnis ausführen. Dies kann in der Realität passieren.

__Datei__

Dies bedeutet die Verwendung von path = os.path.abspath(os.path.dirname(__file__)), aber ich habe festgestellt, dass dies nicht funktioniert

  • py2exe hat kein __file__-Attribut, aber es gibt eine Workaround
  • Wenn Sie IDLE mit execute() ausführen, gibt es kein __file__-Attribut
  • OS X 10.6, wo ich NameError: global name '__file__' is not defined bekomme

Verwandte Fragen mit unvollständigen Antworten:

Ich suche nach einer generischen Lösung, die in allen obigen Anwendungsfällen funktionieren würde.

Aktualisieren

Hier ist das Ergebnis eines Testfalls:

Ausgabe von Python a.py (unter Windows)

a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz

a.py

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

unterverzeichnis/b.py

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

baum

C:.
|   a.py
\---subdir
        b.py
170
sorin

Sie können den Ort des ausgeführten Hauptscripts nicht direkt bestimmen. Manchmal stammte das Skript überhaupt nicht aus einer Datei. Es könnte zum Beispiel von dem interaktiven Interpreter oder dynamisch generiertem Code stammen, der nur im Speicher gespeichert ist.

Sie können jedoch den Speicherort eines Moduls zuverlässig bestimmen, da Module immer aus einer Datei geladen werden. Wenn Sie ein Modul mit dem folgenden Code erstellen und es in demselben Verzeichnis wie Ihr Hauptskript ablegen, kann das Hauptskript das Modul importieren und dieses verwenden, um sich selbst zu finden.

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

Wenn Sie mehrere Hauptskripte in verschiedenen Verzeichnissen haben, benötigen Sie möglicherweise mehr als eine Kopie von module_locator.

Wenn Ihr Hauptskript von einem anderen Tool geladen wird, mit dem Sie keine Module importieren können, die sich zusammen mit Ihrem Skript befinden, haben Sie kein Glück. In solchen Fällen sind die Informationen, nach denen Sie suchen, nirgendwo in Ihrem Programm vorhanden. Ihre beste Wette wäre, einen Fehler bei den Autoren des Tools einzureichen.

77

Zunächst müssen Sie aus inspect und os importieren.

from inspect import getsourcefile
from os.path import abspath

Als nächstes, wo immer Sie die Quelldatei von Ihnen finden möchten, verwenden Sie sie einfach

abspath(getsourcefile(lambda:0))
48
ArtOfWarfare

Ich bin auf ein ähnliches Problem gestoßen, und ich denke, das könnte das Problem lösen:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

Es funktioniert für normale Skripte und im Leerlauf. Ich kann nur sagen, es für andere auszuprobieren!

Meine typische Verwendung:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

Jetzt benutze ich __modpath__ anstelle von __file__.

13
Garrett Berg

Die kurze Antwort lautet: Es gibt keine garantierte Möglichkeit, die gewünschten Informationen zu erhalten. Es gibt jedoch Heuristiken, die in der Praxis fast immer funktionieren. Sie könnten sich anschauen. Wie finde ich den Ort der ausführbaren Datei in C?. Es behandelt das Problem aus Sicht der C-Klasse, aber die vorgeschlagenen Lösungen lassen sich leicht in Python umwandeln.

6
Dale Hagglund

diese Lösung ist auch in ausführbaren Dateien robust

import inspect, os.path

filename = inspect.getframeinfo(inspect.currentframe()).filename
path     = os.path.dirname(os.path.abspath(filename))

In meiner Antwort auf die Frage Importieren von Modulen aus einem übergeordneten Ordner finden Sie verwandte Informationen, einschließlich der Frage, warum meine Antwort die unzuverlässige Variable __file__ nicht verwendet. Diese einfache Lösung sollte mit verschiedenen Betriebssystemen kompatibel sein, da die Module os und inspect Bestandteil von Python sind.

Zunächst müssen Sie Teile der Module inspect und os importieren.

from inspect import getsourcefile
from os.path import abspath

Als nächstes verwenden Sie die folgende Zeile an einer anderen Stelle in Ihrem Python-Code:

abspath(getsourcefile(lambda:0))

Wie es funktioniert:

Aus dem eingebauten Modul os (Beschreibung unten) wird das Werkzeug abspath importiert. 

Betriebssystemroutinen für Mac, NT oder Posix, je nachdem, auf welchem ​​System wir uns befinden.

Dann wird getsourcefile (Beschreibung unten) aus dem eingebauten Modul inspect importiert. 

Holen Sie sich nützliche Informationen von Live-Python-Objekten.

  • abspath(path) gibt die absolute/vollständige Version eines Dateipfads zurück
  • getsourcefile(lambda:0) ruft irgendwie die interne Quelldatei des Lambda-Funktionsobjekts ab, gibt also '<pyshell#nn>' in der Python-Shell oder den Dateipfad des gerade ausgeführten Python-Codes zurück.

Wenn Sie abspath für das Ergebnis von getsourcefile(lambda:0) verwenden, stellen Sie sicher, dass der generierte Dateipfad der vollständige Dateipfad der Python-Datei ist.
Diese erläuterte Lösung basierte ursprünglich auf Code aus der Antwort unter Wie erhalte ich den Pfad der aktuell ausgeführten Datei in Python? .

3
Edward

Dies sollte den Trick plattformübergreifend tun (solange Sie den Interpreter nicht verwenden oder etwas anderes):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys.path[0] ist das Verzeichnis, in dem sich Ihr aufrufendes Skript befindet (der erste Ort, an dem es nach Modulen sucht, die von diesem Skript verwendet werden sollen). Wir können den Namen der Datei selbst am Ende von sys.argv[0] nehmen (was ich mit os.path.basename getan habe). os.path.join klebt sie einfach plattformübergreifend zusammen. os.path.realpath stellt nur sicher, wenn symbolische Links mit anderen Namen als das Skript selbst angezeigt werden, dass wir immer noch den richtigen Namen des Skripts erhalten.

Ich habe keinen Mac. also habe ich das nicht an einem getestet. Bitte lassen Sie mich wissen, ob es funktioniert, wie es scheint. Ich habe dies in Linux (Xubuntu) mit Python 3.4 getestet. Beachten Sie, dass viele Lösungen für dieses Problem auf Macs nicht funktionieren (da ich gehört habe, dass __file__ auf Macs nicht vorhanden ist).

Wenn es sich bei Ihrem Skript um eine symbolische Verknüpfung handelt, wird Ihnen der Pfad der Datei angezeigt, zu der die Verknüpfung besteht (und nicht der Pfad der symbolischen Verknüpfung).

2
Shule

Sie können Path aus dem Modul pathlib verwenden:

from pathlib import Path

# ...

Path(__file__)

Sie können den Aufruf von parent verwenden, um im Pfad weiterzugehen:

Path(__file__).parent
2
Gavriel Cohen

Sie haben einfach angerufen:

path = os.path.abspath(os.path.dirname(sys.argv[0]))

anstatt:

path = os.path.dirname(os.path.abspath(sys.argv[0]))

abspath() gibt den absoluten Pfad von sys.argv[0] an (der Dateiname, in dem sich Ihr Code befindet) und dirname() gibt den Verzeichnispfad ohne Dateinamen zurück.

2
dgbcgx

Wenn der Code aus einer Datei stammt, können Sie seinen vollständigen Namen erhalten

sys._getframe().f_code.co_filename

Sie können den Funktionsnamen auch als f_code.co_name abrufen.

0
Alex Cohn

Meine Lösung lautet:

import os
print(os.path.join(os.getcwd(), __file__))
0
ThienSuBS

Fügen Sie einfach folgendes hinzu:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

Oder:

from sys import *
print(sys.argv[0])
0
H. Kamran