Як отримати абсолютний шлях до файлу в Python


723

З огляду на такий шлях "mydir/myfile.txt", як я можу знайти абсолютний шлях файлу відносно поточного робочого каталогу в Python? Наприклад, у Windows, я можу закінчити:

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

2
Подібне запитання: stackoverflow.com/questions/7165749/…
Raj

Відповіді:


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

Також працює, якщо це вже абсолютний шлях:

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

29
Примітка: На більшості платформ, це еквівалентно виклику функції normpath()наступним чином : normpath(join(os.getcwd(), path)). Тож якщо mydir/myfile.txtцього не зробити os.getcwd(), абсолютний шлях не є реальним шляхом .
coanor

32
@coanor? Без явного кореня mydir/myfile.txtнеявно посилається на шлях всередині поточного робочого каталогу, тому він є еквівалентним ./mydir/myfile.txt. Можливо, це не той шлях, який ви мали намір ввести, але, наскільки я можу, це здається правильним тлумаченням шляху. Не могли б ви детальніше?
jpmc26

2
@ jpmc26 Я точно не дотримуюся коанора, але я б сказав, що (всупереч тому, що я припускав), між аргументом до abspathфункції та реальним файлом немає зв’язку . Ви можете надати будь-яку назву шляху - неіснуючі файли та ієрархії каталогів є прекрасними - і abspath просто вирішить біти шляху (включаючи батьківський " .." елемент " ") і поверне рядок. Це лише рядок, обчислений з поточного каталогу; будь-яке співвідношення з фактичним файлом є випадковим, здається. Спробуйте os.path.abspath("/wow/junk/../blha/hooey"). Це працює.
Майк S

2
@MikeS Я чесно не впевнений, чому це буде несподівана поведінка. Це абсолютний шлях , а не абсолютний файл чи каталог. Якщо ви хочете перевірити існування, зателефонуйте os.path.exists. Навпаки, такі системи, як PowerShell, які наполягають на існуючому шляху зі стандартною функцією роздільної здатності шляху, - це біль.
jpmc26

1
@ jpmc26 Припустити, що шлях - це лише рядок, схожий на ім'я шляху, зовсім не зрозуміло, і суперечить тому, як я думав і говорив про імена шляхів протягом багатьох років. Я цитую Python 3 документи для abspath: "Поверніть нормалізовану абсолютизовану версію шляху імені шляху ". Не "... версія шляху рядка ". Ім'я шляху, визначене Posix, - це "рядок, який використовується для ідентифікації файлу". Документи Python чітко стосуються : "файлова система не доступна для підтвердження існування або природи ". Якщо аргумент тут очевидний, навіщо бути явним ? relpathpathrelpath
Майк S

77

Ви можете використовувати нову бібліотеку Python 3.4 pathlib. (Ви також можете отримати його для Python 2.6 або 2.7, використовуючи pip install pathlib.) Автори писали : "Метою цієї бібліотеки є створення простої ієрархії класів для обробки шляхів файлової системи та звичайних операцій, які користувачі виконують над ними".

Щоб отримати абсолютний шлях у Windows:

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

Або в UNIX:

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

Документи тут: https://docs.python.org/3/library/pathlib.html


4
Дуже корисний. Використання os.path.abspath()дало мені помилку:, AttributeError: 'NoneType' object has no attribute 'startswith'використання Path().resolve()не має однакового файлового шляху. (Linux та Python3.4)
NuclearPeon

23

Ще краще, встановіть модуль (знайдено на PyPI), він об'єднує всі os.pathфункції та інші пов'язані функції в методи на об'єкті, який можна використовувати скрізь, де використовуються рядки:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
>>>

2
Шкода, що вони ніколи не отримували належного модуля абстракції назви файлів у stdlib.
Торстен Марек

1
@Torsten Marek: це біль і давнє упущення.
течія

4
Тепер вони зробили для Python 3.4: pathlib. Дивіться мою відповідь у цій темі.
twasbrillig

У цій відповіді є yypos. Це повинно бути from path import PathтодіPath('mydir/myfile.txt').abspath()
frakman1

Немає помилок, можливо, ви використовували інший pathмодуль. Зв'язаний модуль використовує клас з назвою path.
Том

14

Сьогодні ви також можете використовувати unipathпакет, який базувався на 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
>>>

Я рекомендую використовувати цей пакет, оскільки він пропонує чистий інтерфейс до загальних утиліт os.path .


10

Оновлення для Python 3.4+, pathlibяке фактично відповідає на питання:

from pathlib import Path

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

Якщо вам потрібна лише тимчасова рядок, майте на увазі, що ви можете використовувати Pathоб'єкти з усіма відповідними функціями os.path, включаючи звичайно abspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object

9
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

Зауважте, що expanduserце необхідно (у Unix), якщо вказане вираження для імені файлу (або каталогу) може містити провідне ~/(тильда посилається на домашній каталог користувача) та expandvarsпіклується про будь-які інші змінні середовища (наприклад $HOME).


6

Це завжди отримує правильне ім'я поточного сценарію, навіть коли він викликається з іншого сценарію. Це особливо корисно при використанні subprocess.

import sys,os

filename = sys.argv[0]

звідти ви можете отримати повний шлях сценарію за допомогою:

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

Це також полегшує навігацію по папках, додаючи /..стільки разів, скільки ви хочете перейти "вгору" в ієрархію каталогів.

Щоб отримати cwd:

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

Для батьківського шляху:

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

Поєднуючись "/.."з іншими іменами, ви можете отримати доступ до будь-якого файлу в системі.


Це не те, що просили. Вони запитали про шлях до поточного робочого каталогу, який не є тим самим, що і каталог сценаріїв, хоча іноді вони можуть мати те саме значення.
Елементал творення

3

Модуль osпропонує спосіб знайти abs шлях.

Але більшість шляхів у Linux починаються з ~(tilde), що не дає задовільного результату.

тому ви можете використовувати 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'

встановити його за допомогою python3 -m pip install srblib

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


1

Я вважаю за краще використовувати глобус

ось як перелічити всі типи файлів у вашій поточній папці:

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

ось як перелічити всі (наприклад) .txt файли у вашій поточній папці:

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

ось як перелічити всі типи файлів у вибраній директорії:

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

сподіваюся, що це вам допомогло


2
Ви ніби відповідаєте на інше запитання. Це був не "Як мені отримати шлях?", А "абсолютний шлях". Можна застосувати правильну відповідь ( os.path.abspath()) до будь-якого відносного шляху, який globпередбачає ваші перші два випадки ...
NichtJens

1

якщо ви на mac

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

це дасть вам повний шлях:

print(upload_folder)

покаже такий шлях:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user

1

Якщо хтось використовує python та linux та шукає повний шлях до файлу:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.