Jak uzyskać bezwzględną ścieżkę do pliku w Pythonie

Odpowiedzi:

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

Działa również, jeśli jest to już ścieżka bezwzględna:

>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
Sherbang
źródło
29
Uwaga: W przypadku większości platform, jest to równoznaczne z wywołaniem funkcji normpath()w następujący sposób: normpath(join(os.getcwd(), path)). Więc jeśli mydir/myfile.txtnie os.getcwd(), to ścieżka absolutna nie jest prawdziwą ścieżką .
coanor
32
@coanor? Bez wyraźnego katalogu głównego mydir/myfile.txtdomyślnie odnosi się do ścieżki w bieżącym katalogu roboczym, ponieważ jest to odpowiednik ./mydir/myfile.txt. Być może nie jest to ścieżka, którą zamierzałeś wprowadzić, ale wydaje mi się, że o ile wiem, to poprawna interpretacja ścieżki. Czy mógłbyś opracować?
jpmc26
2
@ jpmc26 Nie do końca podążam za coanor, ale powiedziałbym, że (wbrew temu, co przypuszczałem), nie ma powiązania między argumentem abspathfunkcji a prawdziwym plikiem. Możesz podać dowolne nieistniejące pliki ścieżki i heirarchie katalogów są w porządku - i abspath po prostu rozpozna bitów ścieżki (włączając element katalogu nadrzędnego ..) i zwróci ciąg. To tylko ciąg obliczony z bieżącego katalogu; jak się wydaje, jakakolwiek korelacja z rzeczywistym plikiem jest przypadkowa. Spróbować os.path.abspath("/wow/junk/../blha/hooey"). To działa.
Mike S
2
@MikeS Szczerze mówiąc, nie jestem pewien, dlaczego takie zachowanie byłoby nieoczekiwane. Jest to ścieżka bezwzględna , a nie bezwzględny plik lub katalog. Jeśli chcesz sprawdzić istnienie, zadzwoń os.path.exists. Przeciwnie, systemy takie jak PowerShell, które nalegają na ścieżkę istniejącą ze standardową funkcją rozdzielczości ścieżki, są uciążliwe w użyciu.
jpmc26
1
@ jpmc26 Założenie, że ścieżka jest po prostu łańcuchem, który wygląda jak nazwa ścieżki, nie jest wcale jasne i jest sprzeczne z tym, jak myślałem i mówiłem o ścieżkach od wielu lat. Cytuję dokumenty Pythona 3 dotyczące abspath: „Zwraca znormalizowaną absolutyzowaną wersję ścieżki do ścieżki ”. To nie jest „... wersja ścieżki ciągu ”. Nazwa ścieżki, zgodnie z definicją Posix, to „Ciąg znaków służący do identyfikacji pliku”. Dokumenty Pythona wyraźnie mówią o : „dostęp do systemu plików w celu potwierdzenia istnienia lub charakteru ”. Jeśli argument tutaj jest oczywisty, po co się wyrażać ? relpathpathrelpath
Mike S
77

Możesz użyć nowej biblioteki Python 3.4 pathlib. (Można go również uzyskać w języku Python 2.6 lub 2.7 pip install pathlib.) Autorzy napisali : „Celem tej biblioteki jest zapewnienie prostej hierarchii klas do obsługi ścieżek systemu plików i typowych operacji wykonywanych przez użytkowników”.

Aby uzyskać bezwzględną ścieżkę w systemie Windows:

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

Lub w systemie UNIX:

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

Dokumenty są tutaj: https://docs.python.org/3/library/pathlib.html

twasbrillig
źródło
4
Bardzo pomocny. Użycie os.path.abspath()dało mi błąd: AttributeError: 'NoneType' object has no attribute 'startswith'użycie Path().resolve()nie ma tej samej względnej ścieżki do pliku. (Linux i Python3.4)
NuclearPeon
23

Co więcej, zainstaluj moduł (znaleziony na PyPI), otacza wszystkie os.pathfunkcje i inne powiązane funkcje w metody na obiekcie, z którego można korzystać wszędzie tam, gdzie używane są łańcuchy:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
>>>
Tomek
źródło
2
Szkoda, że ​​nigdy nie dostali odpowiedniego modułu abstrakcji nazw plików do stdlib.
Torsten Marek,
1
@Torsten Marek: to bolesne i długotrwałe zaniedbanie.
przepływ
4
Zrobili teraz dla Pythona 3.4: pathlib. Zobacz moją odpowiedź w tym wątku.
twasbrillig
W tej odpowiedzi są słowa yypos. Powinien on być from path import PathnastępniePath('mydir/myfile.txt').abspath()
frakman1
Brak literówek, być może korzystałeś z innego pathmodułu. Połączony moduł używa klasy o nazwie path.
Tom
10

Aktualizacja dla Python 3.4+, pathlibktóra faktycznie odpowiada na pytanie:

from pathlib import Path

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

Jeśli potrzebujesz tylko tymczasowego ciągu znaków, pamiętaj, że możesz używać Pathobiektów ze wszystkimi odpowiednimi funkcjami, w os.pathtym oczywiście abspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object
Szalony fizyk
źródło
9
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

Zauważ, że expanduserjest to konieczne (w systemie Unix) w przypadku, gdy podane wyrażenie nazwy pliku (lub katalogu) może zawierać wiodące ~/(tylda odnosi się do katalogu domowego użytkownika) i expandvarszajmuje się wszelkimi innymi zmiennymi środowiskowymi (jak $HOME).

Benjimin
źródło
6

To zawsze otrzymuje poprawną nazwę pliku bieżącego skryptu, nawet jeśli jest wywoływany z innego skryptu. Jest to szczególnie przydatne podczas korzystania subprocess.

import sys,os

filename = sys.argv[0]

stamtąd możesz uzyskać pełną ścieżkę skryptu za pomocą:

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

Ułatwia także nawigację po folderach, dodając /..tyle razy, ile chcesz, aby przejść w górę w hierarchii katalogów.

Aby uzyskać cwd:

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

Dla ścieżki nadrzędnej:

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

Łącząc się "/.."z innymi nazwami plików, możesz uzyskać dostęp do dowolnego pliku w systemie.

Lucas Azevedo
źródło
Nie o to pytano. Pytali o ścieżkę w stosunku do bieżącego katalogu roboczego, co nie jest tym samym co katalog skryptu, chociaż czasami mogą mieć tę samą wartość.
The Elemental of Creation
3

Moduł oszapewnia sposób na znalezienie ścieżki abs.

ALE większość ścieżek w Linuksie zaczyna się od ~(tylda), co nie daje zadowalającego wyniku.

więc możesz użyć srblibdo tego.

>>> 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'

zainstaluj za pomocą python3 -m pip install srblib

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

srbcheema1
źródło
1

Wolę używać glob

oto jak wyświetlić listę wszystkich typów plików w bieżącym folderze:

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

oto jak wyświetlić listę wszystkich (na przykład) plików .txt w bieżącym folderze:

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

oto jak wyświetlić listę wszystkich typów plików w wybranym katalogu:

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

mam nadzieję, że to ci pomogło

F. Taylor
źródło
2
Wygląda na to, że odpowiadasz na inne pytanie. Nie było to „Jak zdobyć ścieżkę?”, Ale „ścieżka absolutna”. Można zastosować poprawną odpowiedź ( os.path.abspath()) do dowolnej ścieżki względnej globprzewidzianej dla twoich pierwszych dwóch przypadków ...
NichtJens
1

jeśli jesteś na komputerze Mac

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

da ci to pełną ścieżkę:

print(upload_folder)

pokaże następującą ścieżkę:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
chikwapuro
źródło
1

W przypadku, gdy ktoś używa Pythona i Linuksa i szuka pełnej ścieżki do pliku:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
BND
źródło