os.path.basename () несовместим, и я не уверен, почему - PullRequest
8 голосов
/ 06 марта 2019

При создании программы для резервного копирования моих файлов я обнаружил, что os.path.basename () не работал согласованно. Например:

import os

folder = '\\\\server\\studies\\backup\\backup_files'
os.path.basename(folder)

возвращает 'backup_files'

folder = '\\\\server\\studies'
os.path.basename(folder)

возвращает ''

Я хочу, чтобы вторая функция с базовым именем возвращала 'study', но возвращает пустую строку. Я запустил os.path.split(folder), чтобы посмотреть, как он разбивает строку, и выясняется, что он рассматривает весь путь как каталог, т.е. ('\\\\server\\studies', ' ').

Я не могу понять, как обойти это ... Самое странное, что я провел ту же строчку раньше, и это сработало, но больше не будет! Это как-то связано с самой первой частью, являющейся общей папкой на сетевом диске?

1 Ответ

3 голосов
/ 06 марта 2019

похоже на специфику Windows UNC

UNC-пути можно рассматривать как эквивалент Unix-пути, только с двойной обратной косой чертой в начале.

Обходной путь должен был бы использовать классический rsplit:

>>> r"\\server\studies".rsplit(os.sep,1)[-1]
'studies'

Интересный факт: с 3 путями он работает правильно:

>>> os.path.basename(r"\\a\b\c")
'c'

Теперь, почему это? давайте проверим исходный код ntpath на окнах:

def basename(p):
    """Returns the final component of a pathname"""
    return split(p)[1]

Хорошо, сейчас split

def split(p):
    seps = _get_bothseps(p)
    d, p = splitdrive(p)

сейчас splitdrive

def splitdrive(p):
    """Split a pathname into drive/UNC sharepoint and relative path specifiers.
    Returns a 2-tuple (drive_or_unc, path); either part may be empty.

Просто чтение документации помогает нам понять, что происходит.

Windows sharepoint должен содержать 2 части пути:

\\server\shareroot

Итак, \\server\studies рассматривается как диск, а путь пуст. Не происходит, когда на пути есть 3 части.

Обратите внимание, что это не ошибка, поскольку невозможно использовать \\server как обычный каталог, создавать каталоги ниже и т. Д. *

Обратите внимание, что официальная документация для os.path.basename не упоминает об этом (поскольку os.path вызывает ntpath за кадром), но в нем говорится:

Возвращает базовое имя пути pathname. Это второй элемент пары, возвращаемый путем передачи пути к функции split (). Обратите внимание, что результат этой функции отличается от программы с базовым именем Unix

Эта последняя выделенная часть по крайней мере верна! (и документация для os.path.split() не упоминает эту проблему или даже не говорит о Windows)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...