Warum sollte man beide verwenden, os.path.abspath und os.path.realpath?

98

In mehreren Open Source-Projekten habe ich gesehen, wie Leute os.path.abspath(os.path.realpath(__file__))den absoluten Pfad zur aktuellen Datei ermitteln.

Ich finde das jedoch os.path.abspath(__file__)und os.path.realpath(__file__)produziere das gleiche Ergebnis. os.path.abspath(os.path.realpath(__file__))scheint etwas überflüssig zu sein.

Gibt es einen Grund, warum die Leute das benutzen?

hch
quelle

Antworten:

65

os.path.realpath Dereferenziert symbolische Links auf den Betriebssystemen, die sie unterstützen.

os.path.abspathEntfernt einfach Dinge wie .und ..aus dem Pfad und gibt einen vollständigen Pfad vom Stammverzeichnis des Verzeichnisbaums zur benannten Datei (oder zum Symlink) an.

Zum Beispiel unter Ubuntu

$ ls -l
total 0
-rw-rw-r-- 1 guest guest 0 Jun 16 08:36 a
lrwxrwxrwx 1 guest guest 1 Jun 16 08:36 b -> a

$ python
Python 2.7.11 (default, Dec 15 2015, 16:46:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> from os.path import abspath, realpath

>>> abspath('b')
'/home/guest/play/paths/b'

>>> realpath('b')
'/home/guest/play/paths/a'

Symlinks können relative Pfade enthalten, daher müssen beide verwendet werden. Der innere Aufruf von gibt realpathmöglicherweise einen Pfad mit eingebetteten ..Teilen zurück, der abspathdann entfernt wird.

kdopen
quelle
10
Während diese Antwort den Unterschied zwischen den beiden Funktionen beschreibt, ist es nicht wahr, dass das Ergebnis von Komponenten realpath()enthalten ..kann und die Frage, warum Sie beide verwenden würden, nicht wirklich beantwortet. Jobrads Antwort ist genauer.
Meilen
Für Python 3.7 und Windows versteht Realpath nicht untergeordnete Laufwerke. Bei einem untergeordneten Laufwerk mit dem Quellordner c: \ MyFolder \ Bla gibt realpath also P: \ nicht c: \ MyFolder \ Bla zurück. Weiß jemand, wie man den "richtigen" Weg findet?
Totte Karlsson
Für mich folgten abspathimmer noch Symlinks, wenn das aktuelle Verzeichnis ein Symlink ist. Ich habe diese Antwort nur auf stackoverflow.com/questions/54665065/… gefunden , um dieses Verhalten zu stoppen.
Victor Sergienko
107

Für Ihr angegebenes Szenario gibt es keinen Grund, realpath und abspath zu kombinieren, da os.path.realpathtatsächlich aufgerufen wird, os.path.abspathbevor ein Ergebnis zurückgegeben wird (ich habe Python 2.5 auf Python 3.6 überprüft).

  • os.path.abspath Gibt den absoluten Pfad zurück, löst jedoch KEINE Symlinks in seinem Argument auf.
  • os.path.realpath löst zuerst alle symbolischen Verknüpfungen im Pfad auf und gibt dann den absoluten Pfad zurück.

Wenn Sie jedoch erwarten, dass Ihr Pfad a enthält ~, wird weder abspath noch realpath ~in das Ausgangsverzeichnis des Benutzers aufgelöst, und der resultierende Pfad ist ungültig . Sie müssen verwenden os.path.expanduser, um dies in das Benutzerverzeichnis aufzulösen.

Um eine gründliche Erklärung zu erhalten, sind hier einige Ergebnisse aufgeführt, die ich unter Windows und Linux, in Python 3.4 und Python 2.6 überprüft habe. Das aktuelle Verzeichnis ( ./) ist mein Home-Verzeichnis, das so aussieht:

myhome
|- data (symlink to /mnt/data)
|- subdir (extra directory, for verbose explanation)
# os.path.abspath returns the absolute path, but does NOT resolve symlinks in its argument
os.path.abspath('./')
'/home/myhome'
os.path.abspath('./subdir/../data')
'/home/myhome/data'


# os.path.realpath will resolve symlinks AND return an absolute path from a relative path
os.path.realpath('./')
'/home/myhome'
os.path.realpath('./subdir/../')
'/home/myhome'
os.path.realpath('./subdir/../data')
'/mnt/data'

# NEITHER abspath or realpath will resolve or remove ~.
os.path.abspath('~/data')
'/home/myhome/~/data'

os.path.realpath('~/data')
'/home/myhome/~/data'

# And the returned path will be invalid
os.path.exists(os.path.abspath('~/data'))
False
os.path.exists(os.path.realpath('~/data'))
False

# Use realpath + expanduser to resolve ~
os.path.realpath(os.path.expanduser('~/subdir/../data'))
'/mnt/data'
jobrad
quelle
3
Nett. Um Ihren Standpunkt zu verdeutlichen, sollte Ihr letztes Beispiel seinos.path.realpath(os.path.expanduser('~/subdir/../data'))
Arthur
3
Dann vergessen Sie auch nicht os.path.expandvars, wenn Variablen in einem Pfad verwendet werden
Slavenskij
7

Wenn Sie versuchen, den Pfad einer Verknüpfungsdatei abzurufen, gibt der absolute Pfad den vollständigen Pfad der am Verknüpfungsspeicherort vorhandenen Datei an , während der reale Pfad den ursprünglichen Speicherortpfad der Datei angibt .

Der absolute Pfad os.path.abspath () gibt den vollständigen Pfad der Datei an, die sich im aktuellen Arbeitsverzeichnis oder in dem von Ihnen genannten Verzeichnis befindet.

Der reale Pfad os.path.realpath () gibt den vollständigen Pfad der Datei an, auf die verwiesen wird.

Z.B:

file = "shortcut_folder/filename"
os.path.abspath(file) = "C:/Desktop/shortcut_folder/filename"
os.path.realpath(file) = "D:/PyCharmProjects/Python1stClass/filename"
ExtractTable.com
quelle