Непонимание python os.path.abspath
У меня есть следующий код:
directory = r'D:\images'
for file in os.listdir(directory):
print(os.path.abspath(file))
и я хочу следующий вывод:
- D:\изображения\img1.jpg
- D:\images\img2.jpg и т.д.
Но я получаю другой результат:
- D:\код\img1.jpg
- D:\код\img2.jpg
где D:\code - мой текущий рабочий каталог, и этот результат совпадает с
os.path.normpath(os.path.join(os.getcwd(), file))
Итак, возникает вопрос: какова цель os.path.abspath, пока я должен использовать
os.path.normpath(os.path.join(directory, file))
чтобы получить абсолютный путь REAL моего файла? Покажите реальные варианты использования.
Ответы
Ответ 1
Проблема заключается в вашем понимании os.listdir()
not os.path.abspath()
. os.listdir()
возвращает имена каждого из файлов в каталоге. Это даст вам:
img1.jpg
img2.jpg
...
Когда вы передаете их в os.path.abspath()
, они рассматриваются как относительные пути. Это означает, что это относится к каталогу, из которого вы выполняете свой код. Вот почему вы получаете "D:\code\img1.jpg".
Вместо этого вы хотите присоединиться к именам файлов с указанным вами каталогом.
os.path.abspath(os.path.join(directory, file))
Ответ 2
listdir
создает имена файлов в каталоге без ссылки на имя самого каталога. Без какой-либо другой информации abspath
может только сформировать абсолютный путь из единственного каталога, о котором он может знать: текущий рабочий каталог. Вы всегда можете изменить рабочий каталог перед циклом:
os.chdir(directory)
for f in os.listdir('.'):
print(os.path.abspath(f))
Ответ 3
Нативные функции os.listdir
и os.path
на языке Python довольно низкоуровневые. Итерация через каталог (или ряд нисходящих каталогов) требует, чтобы ваша программа собирала пути к файлам вручную. Может быть удобно определить служебную функцию, которая генерирует пути, которые вам понадобятся только один раз, так что логика сборки пути не должна повторяться в каждой итерации каталогов. Например:
import os
def better_listdir(dirpath):
"""
Generator yielding (filename, filepath) tuples for every
file in the given directory path.
"""
# First clean up dirpath to absolutize relative paths and
# symbolic path names (e.g. `.`, `..`, and `~`)
dirpath = os.path.abspath(os.path.expanduser(dirpath))
# List out (filename, filepath) tuples
for filename in os.listdir(dirpath):
yield (filename, os.path.join(dirpath, filename))
if __name__ == '__main__':
for fname, fpath in better_listdir('~'):
print fname, '->', fpath
В качестве альтернативы существуют модули пути "более высокого уровня", которые можно использовать, например py.path, path.py и pathlib (теперь стандартная часть Python для версии 3.4 и выше, но доступно для 2.7 вперед). Они добавляют зависимости к вашему проекту, но повышают уровень многих аспектов обработки файлов, файлов и файлов.