So erhalten Sie einen absoluten Dateipfad in Python

723

"mydir/myfile.txt"Wie finde ich unter Berücksichtigung eines Pfads wie den absoluten Pfad der Datei relativ zum aktuellen Arbeitsverzeichnis in Python? ZB unter Windows könnte ich am Ende Folgendes haben:

"C:/example/cwd/mydir/myfile.txt"
izb
quelle

Antworten:

1055
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'

Funktioniert auch, wenn es sich bereits um einen absoluten Pfad handelt:

>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
Sherbang
quelle
29
Hinweis: Auf den meisten Plattformen entspricht dies dem Aufrufen der Funktion normpath()wie folgt : normpath(join(os.getcwd(), path)). Wenn Sie mydir/myfile.txtdies nicht tun os.getcwd(), ist der absolute Pfad nicht der reale Pfad .
Coanor
32
@coanor? Ohne explizites Stammverzeichnis wird mydir/myfile.txtimplizit auf einen Pfad innerhalb des aktuellen Arbeitsverzeichnisses verwiesen, der daher äquivalent zu ist ./mydir/myfile.txt. Das ist vielleicht nicht der Pfad, den Sie eingeben wollten, aber es scheint die richtige Interpretation des Pfades zu sein, soweit ich das beurteilen kann. Könnten Sie näher darauf eingehen?
jpmc26
2
@ jpmc26 Ich folge coanor nicht genau, aber ich würde sagen, dass (entgegen meiner Vermutung) keine Verbindung zwischen dem Argument zur abspathFunktion und einer realen Datei besteht. Sie können einen beliebigen Pfadnamen angeben - nicht vorhandene Dateien und Verzeichnishierarchien sind in Ordnung - und abspath löst einfach die Bits des Pfads (einschließlich des übergeordneten Verzeichnisses " .." auf) und gibt eine Zeichenfolge zurück. Dies ist nur eine Zeichenfolge, die aus dem aktuellen Verzeichnis berechnet wurde. Jede Korrelation zu einer tatsächlichen Datei scheint zufällig zu sein. Versuchen Sie es os.path.abspath("/wow/junk/../blha/hooey"). Es klappt.
Mike S
2
@ MikeS Ich bin mir ehrlich gesagt nicht sicher, warum das ein unerwartetes Verhalten wäre. Es ist ein absoluter Pfad , keine absolute Datei oder ein absolutes Verzeichnis. Wenn Sie eine Existenzprüfung wünschen, rufen Sie an os.path.exists. Im Gegenteil, Systeme wie PowerShell, die auf dem Pfad bestehen, der mit der Standardfunktion zur Pfadauflösung vorhanden ist, sind schwierig zu verwenden.
jpmc26
1
@ jpmc26 Die Annahme, dass ein Pfad nur eine Zeichenfolge ist, die wie ein Pfadname aussieht, ist überhaupt nicht klar und widerspricht dem, was ich seit vielen Jahren über Pfadnamen denke und spreche. Ich zitiere den Python 3 - Dokumentation für abspath: „Return eine normalisierte verabsolutierten Version des Pfadname Pfad .“ Keine "... Version des String- Pfades ". Ein Pfadname, wie er von Posix definiert wird, lautet "Eine Zeichenfolge, mit der eine Datei identifiziert wird." In den Python-Dokumenten heißt es explizit relpath: "Auf das Dateisystem wird nicht zugegriffen, um die Existenz oder Art von zu bestätigen path." Wenn das Argument hier offensichtlich ist, warum explizit dafür relpath?
Mike S
77

Sie können die neue Python 3.4-Bibliothek verwenden pathlib. (Sie können es auch für Python 2.6 oder 2.7 verwenden pip install pathlib.) Die Autoren schrieben : "Das Ziel dieser Bibliothek ist es, eine einfache Hierarchie von Klassen bereitzustellen, um Dateisystempfade und die allgemeinen Operationen, die Benutzer über sie ausführen, zu behandeln."

So erhalten Sie einen absoluten Pfad in Windows:

>>> from pathlib import Path
>>> p = Path("pythonw.exe").resolve()
>>> p
WindowsPath('C:/Python27/pythonw.exe')
>>> str(p)
'C:\\Python27\\pythonw.exe'

Oder unter UNIX:

>>> from pathlib import Path
>>> p = Path("python3.4").resolve()
>>> p
PosixPath('/opt/python3/bin/python3.4')
>>> str(p)
'/opt/python3/bin/python3.4'

Dokumente finden Sie hier: https://docs.python.org/3/library/pathlib.html

twasbrillig
quelle
4
Sehr hilfreich. Die Verwendung von os.path.abspath()gab mir einen Fehler: Die AttributeError: 'NoneType' object has no attribute 'startswith'Verwendung Path().resolve()funktioniert nicht mit demselben relativen Dateipfad. (Linux und Python3.4)
NuclearPeon
23

Besser noch, installieren Sie das Modul (gefunden auf PyPI), es umschließt alle os.pathFunktionen und andere verwandte Funktionen in Methoden für ein Objekt, die überall dort verwendet werden können, wo Zeichenfolgen verwendet werden:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
>>>
Tom
quelle
2
Schade, dass sie nie ein richtiges Dateinamen-Abstraktionsmodul in die stdlib bekommen haben.
Torsten Marek
1
@ Torsten Marek: Es ist eine wunde und langjährige Auslassung.
Flow
4
Sie haben jetzt für Python 3.4 : pathlib. Siehe meine Antwort in diesem Thread.
Twasbrillig
Diese Antwort enthält Yypos. Es sollte from path import Pathdann seinPath('mydir/myfile.txt').abspath()
frakman1
Es gibt keine Tippfehler. Möglicherweise haben Sie ein anderes pathModul verwendet. Das verknüpfte Modul verwendet eine Klasse mit dem Namen path.
Tom
14

Heute können Sie auch das unipathPaket verwenden, das auf Folgendem basiert path.py: http://sluggo.scrapping.cc/python/unipath/

>>> from unipath import Path
>>> absolute_path = Path('mydir/myfile.txt').absolute()
Path('C:\\example\\cwd\\mydir\\myfile.txt')
>>> str(absolute_path)
C:\\example\\cwd\\mydir\\myfile.txt
>>>

Ich würde empfehlen, dieses Paket zu verwenden, da es eine saubere Schnittstelle zu gängigen Dienstprogrammen von os.path bietet .


quelle
10

Update für Python 3.4+ pathlib, das die Frage tatsächlich beantwortet:

from pathlib import Path

relative = Path("mydir/myfile.txt")
absolute = relative.absolute()  # absolute is a Path object

Wenn Sie nur eine temporäre Zeichenfolge benötigen, denken Sie daran, dass Sie PathObjekte mit allen relevanten Funktionen verwenden können os.path, einschließlich abspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object
Verrückter Physiker
quelle
9
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

Beachten Sie, dass expanduserdies (unter Unix) erforderlich ist, falls der angegebene Ausdruck für den Namen und den Speicherort der Datei (oder des Verzeichnisses) einen führenden enthält ~/(die Tilde bezieht sich auf das Ausgangsverzeichnis des Benutzers) und expandvarssich um alle anderen Umgebungsvariablen (wie z $HOME. B. ) kümmert .

benjimin
quelle
6

Dadurch wird immer der richtige Dateiname des aktuellen Skripts angezeigt, auch wenn es aus einem anderen Skript heraus aufgerufen wird. Es ist besonders nützlich bei der Verwendung subprocess.

import sys,os

filename = sys.argv[0]

Von dort aus können Sie den vollständigen Pfad des Skripts abrufen mit:

>>> os.path.abspath(filename)
'/foo/bar/script.py'

Es erleichtert auch das Navigieren in Ordnern, indem Sie so /..oft anhängen, wie Sie in der Verzeichnishierarchie nach oben möchten.

So erhalten Sie die cwd:

>>> os.path.abspath(filename+"/..")
'/foo/bar'

Für den übergeordneten Pfad:

>>> os.path.abspath(filename+"/../..")
'/foo'

Durch die Kombination "/.."mit anderen Dateinamen können Sie auf jede Datei im System zugreifen.

Lucas Azevedo
quelle
Dies wurde nicht gefragt. Sie fragten nach einem Pfad in Bezug auf das aktuelle Arbeitsverzeichnis, der nicht mit dem Skriptverzeichnis identisch ist, obwohl sie manchmal denselben Wert haben.
Das Element der Schöpfung
3

Das Modul osbietet eine Möglichkeit, den Abs-Pfad zu finden.

ABER die meisten Pfade in Linux beginnen mit ~(Tilde), was kein zufriedenstellendes Ergebnis liefert.

so können Sie dafür verwenden srblib.

>>> import os
>>> os.path.abspath('~/hello/world')
'/home/srb/Desktop/~/hello/world'
>>> from srblib import abs_path
>>> abs_path('~/hello/world')
'/home/srb/hello/world'

Installieren Sie es mit python3 -m pip install srblib

https://pypi.org/project/srblib/

srbcheema1
quelle
1

Ich bevorzuge Glob

So listen Sie alle Dateitypen in Ihrem aktuellen Ordner auf:

import glob
for x in glob.glob():
    print(x)

So listen Sie alle (zum Beispiel) TXT-Dateien in Ihrem aktuellen Ordner auf:

import glob
for x in glob.glob('*.txt'):
    print(x)

So listen Sie alle Dateitypen in einem ausgewählten Verzeichnis auf:

import glob
for x in glob.glob('C:/example/hi/hello/'):
    print(x)

hoffe das hat dir geholfen

F. Taylor
quelle
2
Sie scheinen eine andere Frage zu beantworten. Es war nicht "Wie bekomme ich einen Pfad?", Sondern "ein absoluter Pfad". Man könnte die richtige Antwort ( os.path.abspath()) auf jeden relativen Pfad anwenden, der globfür Ihre ersten beiden Fälle vorgesehen ist ...
NichtJens
1

wenn Sie auf einem Mac sind

import os
upload_folder = os.path.abspath("static/img/users")

Dies gibt Ihnen einen vollständigen Weg:

print(upload_folder)

zeigt den folgenden Pfad:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
Chikwapuro
quelle
1

Falls jemand Python und Linux verwendet und nach dem vollständigen Pfad zur Datei sucht:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
BND
quelle