Python中是否有内置函数可以替换(或删除)文件扩展名(如果有的话)?
例:
print replace_extension('/home/user/somefile.txt', '.jpg')
Run Code Online (Sandbox Code Playgroud)
在我的例子中:/home/user/somefile.txt
将成为/home/user/somefile.jpg
我不知道它是否重要,但我需要这个我正在编写的SCons模块.(所以也许我可以使用一些SCons特定的功能?)
我想要干净的东西.对字符串中的所有实例进行简单的字符串替换.txt
显然不是很干净.(如果我的文件名是这会失败somefile.txt.txt.txt
)
jet*_*hro 122
尝试os.path.splitext它应该做你想要的.
import os
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg'
Run Code Online (Sandbox Code Playgroud)
JS.*_*JS. 53
扩展AnaPana的答案,如何使用pathlib 删除扩展(Python> = 3.4):
>>> 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
Run Code Online (Sandbox Code Playgroud)
Kat*_*iel 28
正如@jethro所说,这splitext
是一种巧妙的方式.但在这种情况下,自己拆分它很容易,因为扩展必须是最后一段时间后文件名的一部分:
filename = '/home/user/somefile.txt'
print( filename.rsplit( ".", 1 )[ 0 ] )
# '/home/user/somefile'
Run Code Online (Sandbox Code Playgroud)
该rsplit
告诉Python来执行从字符串的右侧开始字符串分割,并1
说执行至多一个分裂(从而使得例如'foo.bar.baz'
- > [ 'foo.bar', 'baz' ]
).由于rsplit
将始终返回非空数组,我们可以安全地索引0
它以获取文件名减去扩展名.
Iva*_*anD 11
我更喜欢使用str.rsplit()的以下单行方法:
my_filename.rsplit('.', 1)[0] + '.jpg'
Run Code Online (Sandbox Code Playgroud)
例子:
>>> my_filename = '/home/user/somefile.txt'
>>> my_filename.rsplit('.', 1)
>>> ['/home/user/somefile', 'txt']
Run Code Online (Sandbox Code Playgroud)
Mic*_*all 11
如果您有多个扩展使用pathlib
和str.replace
工作治疗:
>>> from pathlib import Path
>>> p = Path("/path/to/myfile.tar.gz")
>>> extensions = "".join(p.suffixes)
# any python version
>>> str(p).replace(extensions, "")
'/path/to/myfile'
# python>=3.9
>>> str(p).removesuffix(extensions)
'/path/to/myfile'
Run Code Online (Sandbox Code Playgroud)
>>> p = Path("/path/to/myfile.tar.gz")
>>> extensions = "".join(p.suffixes)
>>> new_ext = ".jpg"
>>> str(p).replace(extensions, new_ext)
'/path/to/myfile.jpg'
Run Code Online (Sandbox Code Playgroud)
如果您还想要一个pathlib
对象输出,那么您显然可以将行包起来Path()
>>> Path(str(p).replace("".join(p.suffixes), ""))
PosixPath('/path/to/myfile')
Run Code Online (Sandbox Code Playgroud)
from pathlib import Path
from typing import Union
PathLike = Union[str, Path]
def replace_ext(path: PathLike, new_ext: str = "") -> Path:
extensions = "".join(Path(path).suffixes)
return Path(str(p).replace(extensions, new_ext))
p = Path("/path/to/myfile.tar.gz")
new_ext = ".jpg"
assert replace_ext(p, new_ext) == Path('/path/to/myfile.jpg')
assert replace_ext(str(p), new_ext) == Path('/path/to/myfile.jpg')
assert replace_ext(p) == Path('/path/to/myfile')
Run Code Online (Sandbox Code Playgroud)
TLDR: 在我看来,替换所有扩展的最佳方法如下。
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(p.with_name(p.name.split('.')[0]).with_suffix('.jpg'))
Run Code Online (Sandbox Code Playgroud)
更长的答案:
执行此操作的最佳方法取决于您的 python 版本以及需要处理的扩展数量。也就是说,我很惊讶没有人提到 pathlib 的with_name
. 我还担心这里的一些答案不处理.
父目录中的 a 。以下是完成扩展替换的几种方法。
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(p.with_name(p.name.split('.')[0]).with_suffix('.jpg'))
Run Code Online (Sandbox Code Playgroud)
import pathlib
p = pathlib.Path('/path/to.my/file.foo')
print(p.with_suffix('.jpg'))
Run Code Online (Sandbox Code Playgroud)
使用pathlibs with_name
(我认为最好的解决方案):
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar')
print(p.with_name(p.stem).with_suffix('.jpg'))
Run Code Online (Sandbox Code Playgroud)
使用functools.reduce
和pathlib的with_suffix
:
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(p.with_name(p.name.split('.')[0]).with_suffix('.jpg'))
Run Code Online (Sandbox Code Playgroud)
Python 3.9+使用 pathlib 和 str.removesuffix:
import pathlib
import functools
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(functools.reduce(lambda v, _: v.with_suffix(''), p.suffixes, p).with_suffix('.jpg'))
print(functools.reduce(lambda v, e: v.with_suffix(e), ['' for _ in p.suffixes] + ['.jpg'], p))
Run Code Online (Sandbox Code Playgroud)
一般来说,我认为使用 pathlib 的解决方案更干净,但并不是每个人都能做到这一点。如果您仍在使用 python 2,我很抱歉。如果你没有 python2 的 pathlib 包,我真的很抱歉。
Python 2.7 兼容使用os.path
:
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(pathlib.Path(str(p).removesuffix(''.join(p.suffixes))).with_suffix('.jpg'))
Run Code Online (Sandbox Code Playgroud)
Python 3.9+使用removesuffix
and os.path
(如果你有 python3.9,为什么不使用pathlib
?):
import os
ps = '/path/to.my/file.foo.bar.baz.quz'
print(os.path.join(os.path.dirname(ps), os.path.basename(ps).split('.')[0] + '.jpg'))
Run Code Online (Sandbox Code Playgroud)
小智 6
另一种方法是使用str.rpartition(sep)
方法。
例如:
filename = '/home/user/somefile.txt'
(prefix, sep, suffix) = filename.rpartition('.')
new_filename = prefix + '.jpg'
print new_filename
Run Code Online (Sandbox Code Playgroud)
对于 Python >= 3.4:
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'
Run Code Online (Sandbox Code Playgroud)