在Python中临时更改目录以执行代码而不影响全局工作目录的方法是什么?

huangapple go评论72阅读模式
英文:

Way to temporarily change the directory in Python to execute code without affecting global working directory?

问题

我需要执行一个操作,而不改变全局工作目录。我的情况是我有几个文件夹,每个文件夹里有一些文件。我需要使用这些文件进行一些计算。最初,我尝试了以下方法:

with os.chdir('/directory'):
    ...需要在其中执行的一些代码

但是出现了AttributeError: __enter__。在网上阅读后,使用with似乎不是一个选项。因此,我正在寻找另一种优雅的方式来实现这个目标。

我还尝试了只使用os语句,像这样:

cwd = os.getcwd()

os.chdir('/directory')
..在目录内运行代码 

os.chdir(cwd)

但这在调试时很麻烦,看起来似乎是一种不好的做法。

英文:

I need to perform an action without changing the global working directory. My case is I have a few folders, and in each, there are a few files. I need to do some computations using those files. Initially, I tried the following:

with os.chdir('/directory'):
    ...some code needing execution inside 

but got AttributeError: __enter__. After reading up online using with seems not to be an option. Therefore I'm looking to find another elegant way of doing so.

I also tried just using os statements like so:

cwd = os.getcwd()

os.chdir('/directory')
..run code inside directory 

os.chdir(cwd)

but this is a pain during debugging and seems like a bad practice.

答案1

得分: 5

你可以编写自己的上下文管理器来临时更改工作目录。

import contextlib

@contextlib.contextmanager
def new_cd(x):
    d = os.getcwd()

    # 这可能会引发异常,但最好让它传播并让调用者处理,因为他们请求了x
    os.chdir(x)

    try:
        yield

    finally:
        # 这也可能引发异常,但如果无法恢复旧的工作目录,你真的不具备找出问题所在的能力。
        os.chdir(d)

with new_cd('/directory'):
    ...
英文:

You can write your own context manager to temporarily change the working directory.

import contextlib


@contextlib.contextmanager
def new_cd(x):
    d = os.getcwd()

    # This could raise an exception, but it's probably
    # best to let it propagate and let the caller
    # deal with it, since they requested x
    os.chdir(x)

    try:
        yield

    finally:
        # This could also raise an exception, but you *really*
        # aren't equipped to figure out what went wrong if the
        # old working directory can't be restored.
        os.chdir(d)


with new_cd('/directory'):
    ...

答案2

得分: 3

考虑生成一个子进程:

import subprocess

subprocess.run(cmd, cwd="/directory")

请参阅https://docs.python.org/3/library/subprocess.html。

英文:

Consider spawning a subprocess:

import subprocess

subprocess.run(cmd, cwd="/directory")

See https://docs.python.org/3/library/subprocess.html.

答案3

得分: 2

你可以创建自己的上下文管理器。这个答案与 @chepner 的类似,但在出错的情况下仍会将当前工作目录还原。

import contextlib
import os

@contextlib.contextmanager
# 暂时切换到不同的工作目录
def temporaryWorkingDirectory(path):
    _oldCWD = os.getcwd()
    os.chdir(os.path.abspath(path))

    try:
        yield
    finally:
        os.chdir(_oldCWD)

我使用以下方式进行了测试:

# 测试
print(os.getcwd())
with temporaryWorkingDirectory("../"):
    print(os.getcwd())
print(os.getcwd())
英文:

You can make your own context manager. This answer is similar @chepner 's, but will still change back the current working directory in case of error.

import contextlib
import os

@contextlib.contextmanager
#temporarily change to a different working directory
def temporaryWorkingDirectory(path):
    _oldCWD = os.getcwd()
    os.chdir(os.path.abspath(path))

    try:
        yield
    finally:
        os.chdir(_oldCWD)

I tested it using this

#test
print(os.getcwd())
with temporaryWorkingDirectory("../"):
    print(os.getcwd())
print(os.getcwd())

huangapple
  • 本文由 发表于 2023年1月8日 23:26:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75048986.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定