如何替换 Python pathlib.Path 中的子字符串?

问题描述 投票:0回答:5

有没有一种简单的方法可以替换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
 的字符串形式的副本,并且必须根据需要转换类型。

python python-3.x pathlib
5个回答
42
投票
你是对的。要将路径 p 中的旧内容替换为新内容,您需要:

p = Path(str(p).replace(old, new))


编辑

我们将路径 p 转换为 str,这样我们就得到了这个 str 方法:

有关 method_descriptor 的帮助:

替换(自身,旧的,新的,计数=-1,/)

返回一个副本,其中所有出现的子字符串 old 都被 new 替换。

否则我们会得到这个 Path 方法:

模块路径库中函数替换的帮助:

替换(自身,目标)

将此路径重命名为给定路径,破坏现有目的地(如果存在),并返回指向给定路径的新 Path 实例。


4
投票
使用 PurePath.with_name() 或 PurePath.with_stem()


2
投票
我最近遇到了类似的问题,并在寻找解决方案时发现了这个线程。与接受的答案相反,我没有将

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')
这种方法的一个优点是它避免了在父位中进行不需要的替换的风险。


2
投票
扩展

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()
 方法


0
投票
我也会本能地使用

str

来进行替换。

如果您想对每个子部分进行一些更改,您也可以分解部分,进行替换,然后重新组合它们:

path = Path(*(p.replace(old, new) for p in path.parts))
    
© www.soinside.com 2019 - 2024. All rights reserved.