在Python中如何从路径获取不带扩展名的文件名

在Python中如何从路径获取不带扩展名的文件名

技术背景

在Python开发中,经常会遇到需要从文件路径中提取不带扩展名的文件名的需求。例如,在文件处理、数据处理或自动化脚本中,需要根据文件名进行一些操作,而不需要扩展名的干扰。Python提供了多种方法来实现这一功能,下面将详细介绍不同Python版本下的实现方式。

实现步骤

Python 3.4+

可以使用pathlib.Path.stem方法来获取不带扩展名的文件名。

1
2
3
from pathlib import Path
print(Path("/path/to/file.txt").stem) # 输出: file
print(Path("/path/to/file.tar.gz").stem) # 输出: file.tar

Python < 3.4

可以结合使用os.path.splitextos.path.basename方法来实现。

1
2
3
import os
print(os.path.splitext(os.path.basename("/path/to/file.txt"))[0]) # 输出: file
print(os.path.splitext(os.path.basename("/path/to/file.tar.gz"))[0]) # 输出: file.tar

处理多个扩展名的情况

已知第一个扩展名

如果已知第一个扩展名,可以使用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) # 输出: thefile

处理任意数量的扩展名

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) # 输出: thefile

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) # 输出: target_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))

使用pathlibremovesuffix

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")) # 输出: ('./data', '.tar')
print(split_extensions("./data.tar.gz")) # 输出: ('./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]) # 输出: images.tar

解决方法是使用pathlib模块或自定义函数来处理多个扩展名的情况。

性能问题

虽然pathlib模块提供了方便的文件路径处理方法,但在性能要求较高的场景下,可能会有一定的性能开销。可以使用一些简单的字符串操作来提高性能,例如:

1
2
3
file = 'D:/ffmpeg/ffmpeg.exe'
name = file.split('/')[-1].rsplit('.', 1)[0]
print(name) # 输出: ffmpeg

这种方法通过简单的字符串分割和反转操作,避免了pathlib模块的一些开销,性能更高。


在Python中如何从路径获取不带扩展名的文件名
https://119291.xyz/posts/how-to-get-filename-without-extension-in-python/
作者
ww
发布于
2025年5月26日
许可协议