8

来自 Python 3.4 的pathlib 库中的新 Path 包似乎是对诸如 之类的方法的强大替代os.path.join(),但我在使用它时遇到了一些麻烦。

我有一条可以从folder_foo/file.csv到的路径long/path/to/folder_foo/file.csv。我用 pandas 读取了 .csv 文件,folder_foo对其进行了修改并希望将其保存到folder_bar/file.csvor long/path/to/folder_bar/file.csv

本质上,我想在 Path 对象中重命名folder_foo为。folder_bar

编辑:示例路径代码

csv_path = Path("long/path/to/folder_foo/file.csv")

尝试

1

csv_path.parents[0] = csv_path.parents[0] + "_clean")

这会导致错误TypeError: unsupported operand type(s) for +: 'PosixPath' and 'str',这意味着您不能按照TypeError: unsupported operand type(s) for +: 'PosixPath' and 'str'中所述+将 aPosixPath与 a结合使用。str

2

为了解决这个问题,我尝试了以下方法:

csv_path.parents[0] = Path(str(csv_path.parents[0]) + "_clean")

然而,这会导致错误:TypeError: '_PathParents' object does not support item assignment

由于PosixPath不是列表,因此此错误是可以理解的。

3

也许.parts是更好的方法,但是

csv_path.parts[-2] = csv_path.parts[-2][:-3] + "bar"

结果:TypeError: 'tuple' object does not support item assignment

问题

如何轻松重命名文件的父文件夹?

4

3 回答 3

6

为了可读性,宁愿把它分开:

bar_folder = csv_path.parent.parent / 'folder_bar'
csv_path2 = bar_folder / csv_path.name

将目标文件夹作为变量还可以让您创建文件夹,例如:

bar_folder.mkdir(exist_ok=True)
于 2018-08-17T13:50:42.447 回答
2

您还可以编写一个小函数来替换您要更改的路径部分。这是一个可运行的示例:

from pathlib import Path

path1 = Path("a/b/c.txt")
path2 = Path("b/c.txt")

def rename_dir(path, src, dst):
    # convert to list so that we can change elements
    parts = list(path.parts)
    
    # replace part that matches src with dst
    parts[parts.index(src)] = dst
    
    return Path(*parts)

rename_dir(path1, 'b', 'q')
#> PosixPath('a/q/c.txt')

rename_dir(path2, 'b', 'q')
#> PosixPath('q/c.txt')

创建于 2021-03-06 10:44:00 PST 由reprexlite v0.4.2

于 2021-03-06T18:46:44.797 回答
0

编辑:找到了一个没有 str() 的更清洁的解决方案

csv_path2 = csv_path.parents[1] / (csv_path.parts[-2][:-3] + "bar") / csv_path.parts[-1]
# result
PosixPath('long/path/to/folder_bar/file.csv')

Path.parents获取文件夹的整个路径减去文件。Path.parents[1]向上 2 级 ( long/path/to/),它仍然是一个 Path 对象。然后我们得到最后一个文件夹名称csv_path.parts[-2],它是一个字符串。我们申请[:-3]获取除 之外的所有字符串字符"foo"。这意味着我们有"folder_". 然后+ "bar"我们得到"folder_bar",它被添加到我们的Path对象中。最后,我们将文件名重新添加到我们的Path对象中/ csv_path.parts[-1]

像黑客一样的解决方案

csv_path = Path(str(csv_path.parents[0])[:-3] + 'bar/' + csv_path.parts[-1])

然而,在我看来,这有点不直观。应该有更干净的解决方案吗?

于 2018-06-21T02:35:01.890 回答