Подтвердить что ты не робот

Непонимание 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 моего файла? Покажите реальные варианты использования.

4b9b3361

Ответ 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 вперед). Они добавляют зависимости к вашему проекту, но повышают уровень многих аспектов обработки файлов, файлов и файлов.