os.path.basename()不一致,我不确定为什么

Man*_*nar 8 python windows python-3.x

在创建一个备份文件的程序时,我发现os.path.basename()不能始终如一地工作。例如:

import os

folder = '\\\\server\\studies\\backup\\backup_files'
os.path.basename(folder)
Run Code Online (Sandbox Code Playgroud)

退货 'backup_files'

folder = '\\\\server\\studies'
os.path.basename(folder)
Run Code Online (Sandbox Code Playgroud)

退货 ''

我希望第二个basename函数返回“研究”,但它返回一个空字符串。我跑去os.path.split(folder)看看它是如何分割字符串的,结果证明它正在考虑将整个路径作为目录,即('\\\\server\\studies', ' ')

我想不通如何解决它。最奇怪的是,我早些时候跑过同一条生产线,但它行得通,但现在已经不行了!它与网络驱动器上的共享文件夹的第一部分有关吗?

Jea*_*bre 5

看起来像 Windows UNC 特异性

UNC 路径可以看作与 unix 路径等效,只是开头有双反斜杠。

解决方法是使用 classic rsplit

>>> r"\\server\studies".rsplit(os.sep,1)[-1]
'studies'
Run Code Online (Sandbox Code Playgroud)

有趣的事实:有 3 条路径,它可以正常工作:

>>> os.path.basename(r"\\a\b\c")
'c'
Run Code Online (Sandbox Code Playgroud)

现在为什么会这样呢?ntpath我们来看看windows下的源码:

def basename(p):
    """Returns the final component of a pathname"""
    return split(p)[1]
Run Code Online (Sandbox Code Playgroud)

现在好吧split

def split(p):
    seps = _get_bothseps(p)
    d, p = splitdrive(p)
Run Code Online (Sandbox Code Playgroud)

现在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.
Run Code Online (Sandbox Code Playgroud)

只需阅读文档即可让我们了解发生了什么。

Windows 共享点必须包含 2 个路径部分:

\\server\shareroot
Run Code Online (Sandbox Code Playgroud)

所以\\server\studies被视为驱动,而路径是空的。当路径中有 3 个部分时不会发生。

请注意,这不是一个错误,因为它不可能\\server像普通目录一样使用,在下面创建目录等......

请注意,官方文档os.path.basename没有提到这一点(因为在幕后os.path调用),但它指出:ntpath

返回路径名路径的基本名称。这是通过将路径传递给函数 split() 返回的对的第二个元素。请注意,该函数的结果与 Unix basename 程序不同

最后强调的部分至少是正确的!(并且文档os.path.split()没有提到这个问题,甚至没有谈论Windows)