关于scons:如何在python中替换(或删除)文件名的扩展名?

How to replace (or strip) an extension from a filename in Python?

python中是否有一个内置函数可以替换(或删除)文件名的扩展名(如果有)?

例子:

1
print replace_extension('/home/user/somefile.txt', '.jpg')

在我的例子中:/home/user/somefile.txt会变成/home/user/somefile.jpg

我不知道它是否重要,但我需要这个为我正在写的一个scons模块。(所以也许我可以使用一些特定于scons的函数?)

我想要些干净的。在字符串中对所有出现的.txt进行简单的字符串替换显然是不干净的。(如果我的文件名是somefile.txt.txt.txt,这将失败)


试试os.path.splitext,它应该做你想做的。

1
2
import os
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg'


扩展anapana的答案,如何使用pathlib删除扩展(python>=3.4):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> from pathlib import Path

>>> filename = Path('/some/path/somefile.txt')

>>> filename_wo_ext = filename.with_suffix('')

>>> filename_replace_ext = filename.with_suffix('.jpg')

>>> print(filename)
/some/path/somefile.ext    

>>> print(filename_wo_ext)
/some/path/somefile

>>> print(filename_replace_ext)
/some/path/somefile.jpg


正如@jethro所说,splitext是一个很好的方法。但在这种情况下,很容易自己拆分它,因为扩展名必须是最后一段时间之后的文件名的一部分:

1
2
3
filename = '/home/user/somefile.txt'
print( filename.rsplit(".", 1 )[ 0 ] )
# '/home/user/somefile'

rsplit告诉python从字符串的右边开始执行字符串拆分,1表示最多执行一个拆分(例如'foo.bar.baz'->[ 'foo.bar', 'baz' ])。由于rsplit总是返回一个非空数组,因此我们可以安全地将0索引到该数组中,以获取文件名减去扩展名。


对于python>=3.4:

1
2
3
4
5
6
7
from pathlib import Path

filename = '/home/user/somefile.txt'

p = Path(filename)
new_filename = p.parent.joinpath(p.stem + '.jpg') # PosixPath('/home/user/somefile.jpg')
new_filename_str = str(new_filename) # '/home/user/somefile.jpg'


我更喜欢使用str.rsplit()的以下一行方法:

1
my_filename.rsplit('.', 1)[0] + '.jpg'

例子:

1
2
3
>>> my_filename = '/home/user/somefile.txt'
>>> my_filename.rsplit('.', 1)
>>> ['/home/user/somefile', 'txt']


另一种方法是使用str.rpartition(sep)方法。

例如:

1
2
3
4
5
6
filename = '/home/user/somefile.txt'
(prefix, sep, suffix) = filename.rpartition('.')

new_filename = prefix + '.jpg'

print new_filename