0

我试图了解以下是如何实现 Unix 命令 pushd 的。具体来说,鉴于它不产生任何结果,因此 yield 命令的目的是什么。

@contextmanager
def pushd(path):
    prev = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(prev)

根据维基百科,“pushd 命令将当前工作目录保存在内存中,因此可以随时返回,可选择更改为新目录”。此代码块的哪一部分执行此定义中的哪些功能?

4

1 回答 1

1

要理解此代码,您必须了解为什么使用 @contextmanager 装饰器。它允许您在with语句中使用某些函数,该函数将为您处理上下文。所以你想在某个目录中做某事然后跳回来——你的动作在你跳入的目录的上下文中是有意义的。所以这个函数的用例看起来像这样:

In [4]: os.chdir('/var')                                                                                                                                                                     

In [5]: os.getcwd()                                                                                                                                                                          
Out[5]: '/var'

In [6]: with pushd('/etc'): 
   ...:     print(os.getcwd()) 
   ...:                                                                                                                                                                                      
/etc

In [7]: os.getcwd()                                                                                                                                                                          
Out[7]: '/var'

如您所见 - 目录已更改为with块内的 /etc,但之后又返回到 /var,类似于 popd 的行为。

在这种情况下,yield 是上下文管理器装饰器 API 的一部分,在这种情况下它不需要返回任何内容。它用于像这样的结构

with open('my_file.txt') as file:
   do_something_with_file(file)

您实际上需要一些资源来处理内部上下文。

请参阅contextlib文档以了解有关模块目标的更多信息。

于 2020-03-18T11:34:42.747 回答