如何使用Python pathlib更改目录

71
使用Python的pathlib(文档)功能更改目录的预期方法是什么?
假设我创建了以下Path对象:
from pathlib import Path
path = Path('/etc')

目前我只知道以下内容,但这似乎有损于pathlib的理念。

import os
os.chdir(str(path))

1
如果您不需要它,可以不使用pathlib - os.chdir('/etc') - furas
我觉得使用pathlib可以使代码更加优雅。但是,既然cd毫不优雅,我还不如用os.chdir('/etc') - Lukas
pathlib 是一个用于处理路径的模块,而不是用于更改目录的。 - furas
3
@furas; 把这个告诉核心开发人员。请查看 Path.read_bytes 和 Path.read_text。 - Jürgen A. Erhard
由于pathlib没有专门针对此功能的功能,因此问题简化为“如何更改目录?”,其中Path实例仅指定目录(并且像os.chdir这样的工具已经使用该规范)。因此,这是一个重复的问题 - 如果稍后添加了该功能,则确实仍将保持重复,因为这也是规范的合法答案 - Karl Knechtel
显示剩余2条评论
3个回答

62

根据评论,我意识到 pathlib 不能帮助更改目录,并且应尽可能避免更改目录。

由于我需要从正确的目录外部调用Python中的bash脚本,因此我选择使用上下文管理器以更清晰的方式更改目录,类似于这个答案

import os
import contextlib
from pathlib import Path

@contextlib.contextmanager
def working_directory(path):
    """Changes working directory and returns to previous on exit."""
    prev_cwd = Path.cwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(prev_cwd)
一个很好的选择是使用subprocess.Popen类的cwd参数,就像这个答案中所示。
如果你正在使用Python<3.6并且path实际上是一个pathlib.Path对象,则需要在chdir语句中使用str(path)

2
这正是我所需要的!我正在测试一个命令行工具,其所需参数取决于cwd,因此我需要移动cwd以测试此功能。但是,如果我以天真的方式编写它,那么当测试失败时,它将抛出意外异常,并且cwd不会被移回,这意味着所有未来的测试都以错误的cwd开始并给出无用的错误。使用上下文管理器意味着我知道它会被移回!我认为try-except-finally块也是有效的,但编写上下文管理器更可靠并节省了多个测试的代码。 - William

25
在Python 3.6或以上版本中,os.chdir()可以直接处理Path对象。实际上,Path对象可以替换标准库中的大多数str路径。

os.chdir(path) 将当前工作目录更改为 path。

此函数支持指定文件描述符。描述符必须引用已打开的目录而不是打开的文件。

新于版本3.3:在某些平台上添加了将路径指定为文件描述符的支持。

从版本3.6开始更改:接受类似路径的对象

import os
from pathlib import Path

path = Path('/etc')
os.chdir(path)

这可能有助于未来的项目,这些项目不需要与3.5或更低版本兼容。


是的,确实非常好。我希望Python社区要么在任何地方都接受pathlib.Path,要么完全放弃它。 - Lukas
@Lukas:我真的很想喜欢它,但目前我无法接受它。而且自从你的评论以来已经过去了三年,我怀疑我永远也无法接受它...而os.path仍将存在。如果它可以完全替代os.path,我可以并且愿意接受它。这就是问题所在。至少对我来说是这样。 - Jürgen A. Erhard
自然而然,这应该是被接受的答案。是的,如果存在一个假设的全面的pathlib.Path.chdir()方法,那么API正交性将更可取 - 但这是次优选择。让我们不要再让完美成为好的敌人了。 - Cecil Curry

1
如果您不介意使用第三方库,则可以执行以下操作:

$ pip install path

然后:
from path import Path

with Path("somewhere"):
    # current working directory is now `somewhere`
    ...
# current working directory is restored to its original value. 

如果您不想使用上下文管理器,可以这样做:
Path("somewhere").cd()
# current working directory is now changed to `somewhere`

18
为了完全清楚,这不是标准库中的pathlib。使用pathlib.Path('x')并不会改变目录。 - Jeremy Woodland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接