如何编写一个装饰器,将当前工作目录恢复到调用修饰函数之前的状态?换句话说,如果我在执行a的函数上使用装饰器,则在调用函数os.chdir()
后不会更改cwd.
给出了装饰者的答案; 它根据请求在函数定义阶段工作.
使用Python 2.5+,您还可以使用上下文管理器在函数调用阶段执行此操作:
from __future__ import with_statement # needed for 2.5 ? Python < 2.6 import contextlib, os @contextlib.contextmanager def remember_cwd(): curdir= os.getcwd() try: yield finally: os.chdir(curdir)
如果在函数调用时需要,可以使用它:
print "getcwd before:", os.getcwd() with remember_cwd(): walk_around_the_filesystem() print "getcwd after:", os.getcwd()
这是一个不错的选择.
编辑:我添加了codeape建议的错误处理.由于我的答案已经通过,所以提供完整的答案,除了所有其他问题是公平的.
该path.py模块(你如果用Python处理脚本路径确实应该用)具有上下文管理器:
subdir = d / 'subdir' #subdir is a path object, in the path.py module with subdir: # here current dir is subdir #not anymore
(来自Roberto Alsina的博客文章)
给定的答案未考虑到包装函数可能引发异常.在这种情况下,永远不会恢复该目录.下面的代码将异常处理添加到以前的答案中.
作为装饰者:
def preserve_cwd(function): @functools.wraps(function) def decorator(*args, **kwargs): cwd = os.getcwd() try: return function(*args, **kwargs) finally: os.chdir(cwd) return decorator
并作为上下文管理器:
@contextlib.contextmanager def remember_cwd(): curdir = os.getcwd() try: yield finally: os.chdir(curdir)