如何在Python中更改目录(cd)?

too*_*php 641 python

cd 如在shell命令中更改工作目录.

如何在Python中更改当前的工作目录?

Mic*_*bbé 717

您可以使用以下命令更改工作目录:

import os

os.chdir(path)
Run Code Online (Sandbox Code Playgroud)

使用此方法时,有两个最佳做法:

  1. 在无效路径上捕获异常(WindowsError,OSError).如果抛出异常,请不要执行任何递归操作,尤其是破坏性操作.它们将在旧路上运行而不是新路径.
  2. 完成后返回旧目录.这可以通过将chdir调用包装在上下文管理器中以异常安全的方式完成,就像Brian M. Hunt在他的回答中所做的那样.

更改子进程中的当前工作目录不会更改父进程中的当前工作目录.对于Python解释器也是如此.您无法使用os.chdir()更改调用进程的CWD.

  • 我认为这是交互式shell中最简单的方法.请注意,在Windows中,您必须使用正斜杠,例如`os.chdir("C:/ path/to/location")` (4认同)
  • [cdunn2001](/sf/users/18479891/)的轻量级[基于装饰的答案](/sf/answers/1692321571/)是现代Python的理想方法.以上答案说明了原因.**除非你认为你知道自己在做什么,否则永远不要在上下文管理器之外调用`os.chdir()`.(_你可能不会._) (3认同)
  • 在 Windows 中,如果复制带有反斜杠的路径,则使用原始字符串会更容易。`r'C:\path\to\location'`。 (2认同)

Bri*_*unt 296

以下是更改工作目录的上下文管理器示例.它比其他地方引用的ActiveState版本更简单,但这可以完成工作.

上下文管理器 cd

import os

class cd:
    """Context manager for changing the current working directory"""
    def __init__(self, newPath):
        self.newPath = os.path.expanduser(newPath)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.newPath)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)
Run Code Online (Sandbox Code Playgroud)

或者使用ContextManager尝试更简洁的等价物(下面).

import subprocess # just to call an arbitrary command e.g. 'ls'

# enter the directory like this:
with cd("~/Library"):
   # we are in ~/Library
   subprocess.call("ls")

# outside the context manager we are back wherever we started.
Run Code Online (Sandbox Code Playgroud)

  • 如果你需要知道你从哪个目录改变了,你可以在 `__enter__` 的末尾添加 `return self`。这样你就可以做 `with cd('foo') as cm:` 并以 `cm.savedPath` 访问前一个目录 (4认同)

Eva*_*ark 136

我会用os.chdir这样的:

os.chdir("/path/to/change/to")
Run Code Online (Sandbox Code Playgroud)

顺便说一下,如果你需要弄清楚你当前的路径,请使用os.getcwd().

更多这里


cdu*_*001 107

cd() 使用生成器和装饰器很容易编写.

from contextlib import contextmanager
import os

@contextmanager
def cd(newdir):
    prevdir = os.getcwd()
    os.chdir(os.path.expanduser(newdir))
    try:
        yield
    finally:
        os.chdir(prevdir)
Run Code Online (Sandbox Code Playgroud)

然后,即使抛出异常,该目录也会被还原:

os.chdir('/home')

with cd('/tmp'):
    # ...
    raise Exception("There's no place like home.")
# Directory is now back to '/home'.
Run Code Online (Sandbox Code Playgroud)

  • **辉煌!**如果[接受的答案](/sf/answers/30220081/)的介绍性评论被注入_this_答案,这将是无法理解的.尽管如此,这个答案的简洁,Python安全的实现保证了我必须给予的所有支持. (5认同)
  • 另外,请注意[这个潜在的错误](http://stackoverflow.com/a/15427892)(忘记`try/finally`). (3认同)
  • 为什么"屈服"而不是"回归"?这应该是发电机吗? (3认同)
  • @NicoBerrogorry,它是一个发电机。请参阅 [contextlib.contextmanager](https://docs.python.org/2/library/contextlib.html) 上的文档。这是Python中非常有用的模式,值得学习。 (2认同)

Bri*_*per 23

如果您使用的Python的一个相对较新的版本,你也可以使用一个上下文管理器,比如这一个:

from __future__ import with_statement
from grizzled.os import working_directory

with working_directory(path_to_directory):
    # code in here occurs within the directory

# code here is in the original directory
Run Code Online (Sandbox Code Playgroud)

UPDATE

如果你喜欢自己动手:

import os
from contextlib import contextmanager

@contextmanager
def working_directory(directory):
    owd = os.getcwd()
    try:
        os.chdir(directory)
        yield directory
    finally:
        os.chdir(owd)
Run Code Online (Sandbox Code Playgroud)

  • **依赖性很差.**Python的内置`contextlib.contextmanager`装饰器很好.请参阅[cdunn2001](/sf/users/18479891/)的[基于装饰的答案](/sf/answers/1692321571/),理想情况下是接受的答案现在. (4认同)

mrd*_*ave 13

正如其他人已经指出的那样,上述所有解决方案只会改变当前进程的工作目录.当您退回到Unix shell时,这会丢失.如果绝望,你可以用这个可怕的黑客改变Unix上的父shell目录:

def quote_against_shell_expansion(s):
    import pipes
    return pipes.quote(s)

def put_text_back_into_terminal_input_buffer(text):
    # use of this means that it only works in an interactive session
    # (and if the user types while it runs they could insert characters between the characters in 'text'!)
    import fcntl, termios
    for c in text:
        fcntl.ioctl(1, termios.TIOCSTI, c)

def change_parent_process_directory(dest):
    # the horror
    put_text_back_into_terminal_input_buffer("cd "+quote_against_shell_expansion(dest)+"\n")
Run Code Online (Sandbox Code Playgroud)

  • **疯狂,脆弱的黑客获得强制性的支持.**没有人应该这样做,尤其是那个"如果用户在运行时打字......"需要注意.尽管如此,它还是反驳了我的反叛领带,看到改变父母的CWD _is_ sort-of,但不是真的可行.Upvotes!支持所有人! (3认同)

PEZ*_*PEZ 11

os.chdir()是Pythonic版本的cd.


Fed*_*oni 11

os.chdir() 是正确的方法.


Ric*_*o D 8

import os

abs_path = 'C://a/b/c'
rel_path = './folder'

os.chdir(abs_path)
os.chdir(rel_path)
Run Code Online (Sandbox Code Playgroud)

您可以同时使用 os.chdir(abs_path) 或 os.chdir(rel_path),无需调用 os.getcwd() 即可使用相对路径。


Yau*_*ich 6

进一步指向Brian指出的方向并基于sh(1.0.8+)

from sh import cd, ls

cd('/tmp')
print ls()
Run Code Online (Sandbox Code Playgroud)