如何编写一个恢复 cwd 的装饰器?

发布于 2024-07-06 07:24:23 字数 91 浏览 6 评论 0原文

如何编写一个装饰器,将当前工作目录恢复到调用装饰函数之前的状态? 换句话说,如果我在执行 os.chdir() 的函数上使用装饰器,则调用函数后 cwd 将不会更改。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你的笑 2024-07-13 07:24:23

装饰器的答案已经给出了; 它按照要求在函数定义阶段工作。

使用 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 的建议添加了错误处理。 由于我的答案已被投票通过,因此可以公平地提供完整的答案,抛开所有其他问题。

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 call stage using a context manager:

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.

离线来电— 2024-07-13 07:24:23

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 的这篇博文

The path.py module (which you really should use if dealing with paths in python scripts) has a context manager:

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 post from Roberto Alsina)

谜泪 2024-07-13 07:24:23

给出的答案没有考虑到包装函数可能会引发异常。 在这种情况下,该目录将永远不会被恢复。 下面的代码在前面的答案中添加了异常处理。

作为装饰器:

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)

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)
一人独醉 2024-07-13 07:24:23

你不需要为你写它。 在 python 3.11 中,开发人员已经为您编写了它。 在 github.com 上查看代码

import contextlib
with contextlib.chdir('/path/to/cwd/to'):
    pass

You dont need to write it for you. With python 3.11, the developers have written it for you. Check out their code at github.com.

import contextlib
with contextlib.chdir('/path/to/cwd/to'):
    pass
貪欢 2024-07-13 07:24:23
def preserve_cwd(function):
   def decorator(*args, **kwargs):
      cwd = os.getcwd()
      result = function(*args, **kwargs)
      os.chdir(cwd)
      return result
   return decorator

它的使用方法如下:

@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
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文