在Python中如何从路径获取不带扩展名的文件名
技术背景
在Python开发中,经常会遇到需要从文件路径中提取不带扩展名的文件名的需求。例如,在文件处理、数据处理或自动化脚本中,需要根据文件名进行一些操作,而不需要扩展名的干扰。Python提供了多种方法来实现这一功能,下面将详细介绍不同Python版本下的实现方式。
实现步骤
Python 3.4+
可以使用pathlib.Path.stem
方法来获取不带扩展名的文件名。
1 2 3
| from pathlib import Path print(Path("/path/to/file.txt").stem) print(Path("/path/to/file.tar.gz").stem)
|
Python < 3.4
可以结合使用os.path.splitext
和os.path.basename
方法来实现。
1 2 3
| import os print(os.path.splitext(os.path.basename("/path/to/file.txt"))[0]) print(os.path.splitext(os.path.basename("/path/to/file.tar.gz"))[0])
|
处理多个扩展名的情况
已知第一个扩展名
如果已知第一个扩展名,可以使用rsplit
方法。
1 2 3 4
| from pathlib import Path pth = Path('foo/bar/baz.baz/thefile.tar.gz') fn = pth.name.rsplit('.tar')[0] print(fn)
|
处理任意数量的扩展名
1 2 3 4 5 6 7
| from pathlib import Path pth = Path('./thefile.tar.gz.bz.7zip') fn = pth.name for s in pth.suffixes: fn = fn.rsplit(s)[0] break print(fn)
|
Python 3.9+
使用removesuffix
方法可以更方便地移除所有扩展名。
1 2 3 4
| from pathlib import Path file_path = Path("/path/to.some/target_name.foo.bar.txt") name = file_path.name.removesuffix("".join(file_path.suffixes)) print(name)
|
核心代码
自定义函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import os
def get_filename_without_extension(file_path): file_basename = os.path.basename(file_path) filename_without_extension = file_basename.split('.')[0] return filename_without_extension
example_paths = [ "FileName", "./FileName", "../../FileName", "FileName.txt", "./FileName.txt.zip.asc", "/path/to/some/FileName", "/path/to/some/FileName.txt", "/path/to/some/FileName.txt.zip.asc" ]
for example_path in example_paths: print(get_filename_without_extension(example_path))
|
使用pathlib
和removesuffix
1 2 3 4 5 6 7 8
| from pathlib import Path
def split_extensions(path: str | Path) -> tuple[str, str]: ext = "".join(Path(path).suffixes) return str(path).removesuffix(ext), ext
print(split_extensions("./data.tar")) print(split_extensions("./data.tar.gz"))
|
最佳实践
- 对于Python 3.4及以上版本,推荐使用
pathlib.Path.stem
方法,因为它提供了更面向对象的文件路径处理方式,代码更简洁易读。 - 如果需要处理多个扩展名的情况,根据具体情况选择合适的方法。如果已知第一个扩展名,使用
rsplit
方法;如果需要移除所有扩展名,使用Python 3.9+的removesuffix
方法。 - 对于跨平台的文件路径处理,建议使用
pathlib
模块,它会自动处理不同操作系统的路径分隔符。
常见问题
os.path.splitext
无法处理多个扩展名
os.path.splitext
只能移除最后一个扩展名,如果文件有多个扩展名,它无法满足需求。例如:
1 2 3 4
| import os file_path = '/home/dc/images.tar.gz' file_name = os.path.basename(file_path) print(os.path.splitext(file_name)[0])
|
解决方法是使用pathlib
模块或自定义函数来处理多个扩展名的情况。
性能问题
虽然pathlib
模块提供了方便的文件路径处理方法,但在性能要求较高的场景下,可能会有一定的性能开销。可以使用一些简单的字符串操作来提高性能,例如:
1 2 3
| file = 'D:/ffmpeg/ffmpeg.exe' name = file.split('/')[-1].rsplit('.', 1)[0] print(name)
|
这种方法通过简单的字符串分割和反转操作,避免了pathlib
模块的一些开销,性能更高。