python 如何编写恢复 cwd 的装饰器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/169070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I write a decorator that restores the cwd?
提问by Daryl Spitzer
How do I write a decorator that restores the current working directory to what it was before the decorated function was called? In other words, if I use the decorator on a function that does an os.chdir()
, the cwd will not be changed after the function is called.
如何编写一个装饰器,将当前工作目录恢复到调用装饰函数之前的状态?换句话说,如果我在执行 an 的函数上使用装饰器,则os.chdir()
在调用该函数后不会更改 cwd。
采纳答案by CharlesB
The path.pymodule (which you really should use if dealing with paths in python scripts) has a context manager:
该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
(credits goes to this blog postfrom Roberto Alsina)
(学分来自 Roberto Alsina 的这篇博文)
回答by tzot
The answer for a decorator has been given; it works at the function definition stage as requested.
已经给出了装饰器的答案;它按要求在函数定义阶段工作。
With Python 2.5+, you also have an option to do that at the function callstage using a context manager:
使用 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)
which can be used if needed at the function call time as:
如果需要,可以在函数调用时使用它:
print "getcwd before:", os.getcwd()
with remember_cwd():
walk_around_the_filesystem()
print "getcwd after:", os.getcwd()
It's a nice option to have.
这是一个不错的选择。
EDIT: I added error handling as suggested by codeape. Since my answer has been voted up, it's fair to offer a complete answer, all other issues aside.
编辑:我按照codeape的建议添加了错误处理。由于我的答案已被投票通过,因此提供一个完整的答案是公平的,抛开所有其他问题。
回答by codeape
The given answers fail to take into account that the wrapped function may raise an exception. In that case, the directory will never be restored. The code below adds exception handling to the previous answers.
给定的答案没有考虑到包装的函数可能会引发异常。在这种情况下,该目录将永远不会被恢复。下面的代码为之前的答案添加了异常处理。
as a decorator:
作为装饰者:
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
and as a context manager:
并作为上下文管理器:
@contextlib.contextmanager
def remember_cwd():
curdir = os.getcwd()
try:
yield
finally:
os.chdir(curdir)
回答by Daryl Spitzer
def preserve_cwd(function):
def decorator(*args, **kwargs):
cwd = os.getcwd()
result = function(*args, **kwargs)
os.chdir(cwd)
return result
return decorator
Here's how it's used:
这是它的使用方法:
@preserve_cwd
def test():
print 'was:',os.getcwd()
os.chdir('/')
print 'now:',os.getcwd()
>>> print os.getcwd()
/Users/dspitzer
>>> test()
was: /Users/dspitzer
now: /
>>> print os.getcwd()
/Users/dspitzer