os.path.basename() непоследователен, и я не уверен, почему

#python #python-3.x #windows

#python #python-3.x #Windows

Вопрос:

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

 import os

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

ВОЗВРАТ 'backup_files'

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

ВОЗВРАТ ''

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

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

Комментарии:

1. Взгляните на pathlib .

Ответ №1:

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

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

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

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

Забавный факт: с 3 путями это работает должным образом:

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

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

 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 части пути:

 \servershareroot
  

So \serverstudies рассматривается как диск, а путь пуст. Не происходит, когда в пути есть 3 части.

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

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

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

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