2

这是我基本上想做的事情:

import sh, os

with sh.cd('/tmp'):
  print os.getcwd()

print os.getcwd()

我收到以下错误

line 3, in <module>
    with sh.cd('/tmp'):
AttributeError: __exit__

我在这里想念什么?是否有替代解决方案可以在上下文中更改目录?

4

2 回答 2

6

您不能只使用任何类/函数作为上下文管理器,它必须以这种方式实际显式实现,使用contextlib.contextmanager函数上的装饰器,或者在类的情况下,通过定义__enter____exit__实例方法。

您正在使用的sh.cd功能只是一个包装器os.chdir

>>> import sh
>>> sh.cd
<bound method Environment.b_cd of {}>

b_cd定义为:

def b_cd(self, path):
    os.chdir(path)

如您所见,这只是一个普通功能;它不能用作上下文管理器。

whereswalden 提供的链接显示了一种实现您想要作为一个类的行为的好方法。它可以类似地实现为这样的函数:

import contextlib
import os

@contextlib.contextmanager
def cd(path):
   old_path = os.getcwd()
   os.chdir(path)
   try:
       yield
   finally:
       os.chdir(old_path)

示例用法:

print(os.getcwd())
with cd("/"):
    print os.getcwd()
print(os.getcwd())

输出:

'/home/dan'
'/'
'/home/dan'
于 2014-06-28T18:15:54.983 回答
2

sh现在具有pushd()可以用作上下文管理器来临时更改当前目录的功能:

import sh

with sh.pushd("/tmp"):
    sh.touch("a_file")

https://amoffat.github.io/sh/sections/command_class.html?highlight=pushd#pushd

于 2021-08-29T19:03:41.420 回答