我可以使用哪个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
我可以使用哪个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
当前回答
在你的例子中,你还需要从右边去掉斜杠来返回c:
>>> import os
>>> path = 'a/b/c/'
>>> path = path.rstrip(os.sep) # strip the slash from the right side
>>> os.path.basename(path)
'c'
第二个层面:
>>> os.path.filename(os.path.dirname(path))
'b'
更新:我认为lazyr提供了正确的答案。我的代码将无法在unix系统上使用类似windows的路径,而在windows系统上与类似unix的路径相反。
其他回答
如果您在一个目录中有许多文件,并希望将这些文件名存储到一个列表中。使用下面的代码。
import os as os
import glob as glob
path = 'mypath'
file_list= []
for file in glob.glob(path):
data_file_list = os.path.basename(file)
file_list.append(data_file_list)
我从来没有见过双开的路,它们存在吗?python模块os的内置特性在这些方面失败了。所有其他工作,还有你用os.path.normpath()给出的警告:
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', 'a/./b/c', 'a\b/c']
for path in paths:
os.path.basename(os.path.normpath(path))
也许只是我的all in one解决方案,没有重要的一些新的(考虑tempfile创建临时文件:D)
import tempfile
abc = tempfile.NamedTemporaryFile(dir='/tmp/')
abc.name
abc.name.replace("/", " ").split()[-1]
获取abc.name的值将是这样的字符串:'/tmp/tmpks5oksk7' 所以我可以用空格.replace("/", " ")替换/,然后调用split()。它会返回一个列表,我得到 列表中最后一个带有[-1]的元素
不需要导入任何模块。
在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格式的输入字符串,这对于跨平台比较子路径非常有用。
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])