我可以使用哪个Python库从路径中提取文件名,而不管操作系统或路径格式是什么?

例如,我希望所有这些路径都返回c:

a/b/c/
a/b/c
\a\b\c
\a\b\c\
a\b\c
a/b/../../a/b/c/
a/b/../../a/b/c

当前回答

这是工作!

os.path.basename(name)

但是你不能在Linux中通过Windows文件路径获取文件名。Windows。 操作系统。不同操作系统上不同模块的路径加载:

Linux - posixpath Windows - npath

所以你可以用os。路径总是得到正确的结果

其他回答

在Python 2和3中,使用模块pathlib2:

import posixpath  # to generate unix paths
from pathlib2 import PurePath, PureWindowsPath, PurePosixPath

def path2unix(path, nojoin=True, fromwinpath=False):
    """From a path given in any format, converts to posix path format
    fromwinpath=True forces the input path to be recognized as a Windows path (useful on Unix machines to unit test Windows paths)"""
    if not path:
        return path
    if fromwinpath:
        pathparts = list(PureWindowsPath(path).parts)
    else:
        pathparts = list(PurePath(path).parts)
    if nojoin:
        return pathparts
    else:
        return posixpath.join(*pathparts)

用法:

In [9]: path2unix('lala/lolo/haha.dat')
Out[9]: ['lala', 'lolo', 'haha.dat']

In [10]: path2unix(r'C:\lala/lolo/haha.dat')
Out[10]: ['C:\\', 'lala', 'lolo', 'haha.dat']

In [11]: path2unix(r'C:\lala/lolo/haha.dat') # works even with malformatted cases mixing both Windows and Linux path separators
Out[11]: ['C:\\', 'lala', 'lolo', 'haha.dat']

使用您的测试用例:

In [12]: testcase = paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
    ...: ...     'a/b/../../a/b/c/', 'a/b/../../a/b/c']

In [14]: for t in testcase:
    ...:     print(path2unix(t)[-1])
    ...:
    ...:
c
c
c
c
c
c
c

这里的思想是将所有路径转换为pathlib2的统一内部表示形式,根据平台使用不同的解码器。幸运的是,pathlib2包含一个名为PurePath的通用解码器,它可以在任何路径上工作。如果这不起作用,您可以使用fromwinpath=True强制识别windows路径。这将把输入字符串分成几个部分,最后一个是你要找的叶子,因此是path2unix(t)[-1]。

如果参数nojoin=False,则路径将被连接回来,因此输出只是转换为Unix格式的输入字符串,这对于跨平台比较子路径非常有用。

fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]

这将返回:paint.exe

更改关于您的路径或操作系统的split函数的sep值。

Windows分隔符可以是Unix文件名或Windows路径。Unix分隔符只能存在于Unix路径中。Unix分隔符表示非windows路径。

下面将通过操作系统特定的分隔符剥离(切割尾随分隔符),然后拆分并返回最右边的值。它很丑,但基于上面的假设很简单。如果假设不正确,请更新,我将更新此响应以匹配更准确的条件。

a.rstrip("\\\\" if a.count("/") == 0 else '/').split("\\\\" if a.count("/") == 0 else '/')[-1]

示例代码:

b = ['a/b/c/','a/b/c','\\a\\b\\c','\\a\\b\\c\\','a\\b\\c','a/b/../../a/b/c/','a/b/../../a/b/c']

for a in b:

    print (a, a.rstrip("\\" if a.count("/") == 0 else '/').split("\\" if a.count("/") == 0 else '/')[-1])

有一个函数返回你想要的结果

import os
print(os.path.basename(your_path))

警告:在POSIX系统上使用os.path.basename()从windows样式的路径(例如。"C:\\my\\file.txt"),则会返回整个路径。

下面的例子来自交互式python shell在Linux主机上运行:

Python 3.8.2 (default, Mar 13 2020, 10:14:16)
[GCC 9.3.0] on Linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> filepath = "C:\\my\\path\\to\\file.txt" # A Windows style file path.
>>> os.path.basename(filepath)
'C:\\my\\path\\to\\file.txt'

我最喜欢的是:

filename = fullname.split(os.sep)[-1]