有没有一种简单的方法可以替换Python中
pathlib.Path
对象中的子字符串? pathlib 模块在很多方面比将路径存储为 str
和使用
os.path
、
glob.glob
等(内置于
pathlib
中)更好。但我经常使用遵循某种模式的文件,并且经常替换路径中的子字符串来访问其他文件:
data/demo_img.png
data/demo_img_processed.png
data/demo_spreadsheet.csv
以前我可以做:
img_file_path = "data/demo_img.png"
proc_img_file_path = img_file_path.replace("_img.png", "_img_proc.png")
data_file_path = img_file_path.replace("_img.png", "_spreadsheet.csv")
pathlib
可以用
with_suffix()
方法替换文件扩展名,但只接受扩展名作为有效后缀。解决方法是:
import pathlib
import os
img_file_path = pathlib.Path("data/demo_img.png")
proc_img_file_path = pathlib.Path(str(img_file_path).replace("_img.png", "_img_proc.png"))
# os.fspath() is available in Python 3.6+ and is apparently safer than str()
data_file_path = pathlib.Path(os.fspath(img_file_path).replace("_img.png", "_img_proc.png"))
转换为字符串来进行替换并重新转换为
Path
对象似乎很费力。假设我从来没有
img_file_path
的字符串形式的副本,并且必须根据需要转换类型。
p = Path(str(p).replace(old, new))
我们将路径 p 转换为 str,这样我们就得到了这个 str 方法:
有关 method_descriptor 的帮助:否则我们会得到这个 Path 方法:替换(自身,旧的,新的,计数=-1,/)
返回一个副本,其中所有出现的子字符串 old 都被 new 替换。
模块路径库中函数替换的帮助:替换(自身,目标)
将此路径重命名为给定路径,破坏现有目的地(如果存在),并返回指向给定路径的新 Path 实例。
pathlib.Path
对象转换为字符串。相反,我使用了它的
parent
和 name
属性(name
本身就是一个字符串),以及
joinpath()
方法。这是代码:
In [2]: from pathlib import Path
In [3]: img_file_path = Path('data/demo_img.png')
In [4]: parent, name = img_file_path.parent, img_file_path.name
In [5]: proc_fn = name.replace('_img.png', '_img_proc.png')
...: data_fn = name.replace('_img.png', '_spreadsheet.csv')
In [6]: proc_img_file_path = Path(parent).joinpath(proc_fn)
...: data_img_file_path = Path(parent).joinpath(data_fn)
In [7]: proc_img_file_path
Out[7]: WindowsPath('data/demo_img_proc.png')
In [8]: data_img_file_path
Out[8]: WindowsPath('data/demo_spreadsheet.csv')
这种方法的一个优点是它避免了在父位中进行不需要的替换的风险。
ibykovsky的答案,.with_name()
和
.with_stem()
方法是在3.9+中解决这个问题的干净方法。 与Tonechas 的答案 相同,这避免了无意中更改父部件的任何风险。 对于问题中的例子,我们可以这样写:
import pathlib
p = pathlib.Path("data/demo_img.png")
# Simple case of appending extra text to the Path.stem does not need to use str.replace()
p_proc = p.with_stem(p.stem + "_proc")
# More complex case uses str.replace() on the Path.name
p_data = p.with_name(p.name.replace("_img.png", "_spreadsheet.csv"))
第一个替换只是将字符串附加到词干,因此不需要使用str.replace()
。但请注意,通过词干进行替换意味着无论后缀是什么(例如,
.jpg
以及
.png
)都将进行替换,这与OP不同。这可能是也可能不是您想要的。交换后缀可以使用
.with_suffix()
来完成,但如果父部分需要替换,那么这种方法会变得更加笨拙。虽然 3.12 中引入了
.with_parent()
,但没有
.with_segments()
方法
str
来进行替换。如果您想对每个子部分进行一些更改,您也可以分解部分,进行替换,然后重新组合它们:
path = Path(*(p.replace(old, new) for p in path.parts))