Как получить абсолютный путь к файлу в Python

726

Учитывая путь, такой как "mydir/myfile.txt", как мне найти абсолютный путь файла относительно текущего рабочего каталога в Python? Например, на Windows, я мог бы в конечном итоге:

"C:/example/cwd/mydir/myfile.txt"
IZB
источник
2
Аналогичный вопрос: stackoverflow.com/questions/7165749/…
Радж

Ответы:

1057
>>> 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'
sherbang
источник
29
Примечание: На большинстве платформ, это эквивалентно вызову функции normpath()следующим образом : normpath(join(os.getcwd(), path)). Так что, если mydir/myfile.txtне под os.getcwd(), абсолютный путь не является реальным путем .
коанор
32
@coanor? Без явного корня mydir/myfile.txtнеявно ссылается на путь в текущем рабочем каталоге, который, следовательно, эквивалентен ./mydir/myfile.txt. Возможно, это не тот путь, который вы намеревались ввести, но, насколько я могу судить, это похоже на правильную интерпретацию пути. Не могли бы вы уточнить?
jpmc26
2
@ jpmc26 Я не совсем следую за coanor, но я бы сказал, что (вопреки тому, что я предположил), нет никакой связи между аргументом abspathфункции и реальным файлом. Вы могли бы указать любые пути-несуществующие файлы и каталоги в порядке, и abspath просто разрешит биты пути (включая ..элемент родительского каталога " ") и вернет строку. Это просто строка, вычисленная из текущего каталога; кажется, что любая корреляция с реальным файлом является случайной. Попробуй os.path.abspath("/wow/junk/../blha/hooey"). Оно работает.
Майк С.
2
@MikeS Я, честно говоря, не уверен, почему это было бы неожиданным поведением. Это абсолютный путь , а не абсолютный файл или каталог. Если вы хотите проверить существование, позвоните os.path.exists. Наоборот, такие системы, как PowerShell, которые настаивают на пути, существующем со стандартной функцией разрешения пути, являются трудной задачей.
jpmc26
1
@ jpmc26 Предполагать, что путь - это просто строка, которая выглядит как имя пути, не совсем понятно, и это противоречит тому, как я думал и говорил о путях в течение многих лет. Я цитирую документы Python 3 для abspath: «Вернуть нормализованную абсолютизированную версию пути пути ». Не "... версия пути строки ". Путь, как определено Posix, это «Строка, которая используется для идентификации файла». В документации по Python явно говорится : «к файловой системе нет доступа, чтобы подтвердить существование или природу ». Если аргумент здесь очевиден, зачем быть явным для ? relpathpathrelpath
Майк С.
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

twasbrillig
источник
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
@ Торстен Марек: это больное и давнее упущение.
поток
4
Теперь они сделали для Python 3.4: pathlib. Смотрите мой ответ в этой теме.
twasbrillig
В этом ответе есть yypo. Это должно быть 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).

benjimin
источник
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предоставляет способ найти путь пресса.

НО большинство путей в Linux начинаются с ~(тильды), что не дает удовлетворительного результата.

так что вы можете использовать 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/

srbcheema1
источник
1

Я предпочитаю использовать glob

Вот как можно перечислить все типы файлов в текущей папке:

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
указанному
1

если ты на маке

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

это даст вам полный путь:

print(upload_folder)

покажет следующий путь:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
chikwapuro
источник
1

Если кто-то использует Python и Linux и ищет полный путь к файлу:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
BND
источник