How do I change the working directory in Python?

前端 未结 14 1145
天涯浪人
天涯浪人 2020-11-22 01:59

cd is the shell command to change the working directory.

How do I change the current working directory in Python?

相关标签:
14条回答
  • 2020-11-22 02:06

    If you're using a relatively new version of Python, you can also use a context manager, such as this one:

    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
    

    UPDATE

    If you prefer to roll your own:

    import os
    from contextlib import contextmanager
    
    @contextmanager
    def working_directory(directory):
        owd = os.getcwd()
        try:
            os.chdir(directory)
            yield directory
        finally:
            os.chdir(owd)
    
    0 讨论(0)
  • 2020-11-22 02:06

    os.chdir() is the right way.

    0 讨论(0)
  • 2020-11-22 02:08

    Here's an example of a context manager to change the working directory. It is simpler than an ActiveState version referred to elsewhere, but this gets the job done.

    Context Manager: 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)
    

    Or try the more concise equivalent(below), using ContextManager.

    Example

    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.
    
    0 讨论(0)
  • 2020-11-22 02:08

    As already pointed out by others, all the solutions above only change the working directory of the current process. This is lost when you exit back to the Unix shell. If desperate you can change the parent shell directory on Unix with this horrible hack:

    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")
    
    0 讨论(0)
  • 2020-11-22 02:10

    If You would like to perform something like "cd.." option, just type:

    os.chdir("..")

    it is the same as in Windows cmd: cd.. Of course import os is neccessary (e.g type it as 1st line of your code)

    0 讨论(0)
  • 2020-11-22 02:10

    Changing the current directory of the script process is trivial. I think the question is actually how to change the current directory of the command window from which a python script is invoked, which is very difficult. A Bat script in Windows or a Bash script in a Bash shell can do this with an ordinary cd command because the shell itself is the interpreter. In both Windows and Linux Python is a program and no program can directly change its parent's environment. However the combination of a simple shell script with a Python script doing most of the hard stuff can achieve the desired result. For example, to make an extended cd command with traversal history for backward/forward/select revisit, I wrote a relatively complex Python script invoked by a simple bat script. The traversal list is stored in a file, with the target directory on the first line. When the python script returns, the bat script reads the first line of the file and makes it the argument to cd. The complete bat script (minus comments for brevity) is:

    if _%1 == _. goto cdDone
    if _%1 == _? goto help
    if /i _%1 NEQ _-H goto doCd
    :help
    echo d.bat and dSup.py 2016.03.05. Extended chdir.
    echo -C = clear traversal list.
    echo -B or nothing = backward (to previous dir).
    echo -F or - = forward (to next dir).
    echo -R = remove current from list and return to previous.
    echo -S = select from list.
    echo -H, -h, ? = help.
    echo . = make window title current directory.
    echo Anything else = target directory.
    goto done
    
    :doCd
    %~dp0dSup.py %1
    for /F %%d in ( %~dp0dSupList ) do (
        cd %%d
        if errorlevel 1 ( %~dp0dSup.py -R )
        goto cdDone
    )
    :cdDone
    title %CD%
    :done
    

    The python script, dSup.py is:

    import sys, os, msvcrt
    
    def indexNoCase ( slist, s ) :
        for idx in range( len( slist )) :
            if slist[idx].upper() == s.upper() :
                return idx
        raise ValueError
    
    # .........main process ...................
    if len( sys.argv ) < 2 :
        cmd = 1 # No argument defaults to -B, the most common operation
    elif sys.argv[1][0] == '-':
        if len(sys.argv[1]) == 1 :
            cmd = 2 # '-' alone defaults to -F, second most common operation.
        else :
            cmd = 'CBFRS'.find( sys.argv[1][1:2].upper())
    else :
        cmd = -1
        dir = os.path.abspath( sys.argv[1] ) + '\n'
    
    # cmd is -1 = path, 0 = C, 1 = B, 2 = F, 3 = R, 4 = S
    
    fo = open( os.path.dirname( sys.argv[0] ) + '\\dSupList', mode = 'a+t' )
    fo.seek( 0 )
    dlist = fo.readlines( -1 )
    if len( dlist ) == 0 :
        dlist.append( os.getcwd() + '\n' ) # Prime new directory list with current.
    
    if cmd == 1 : # B: move backward, i.e. to previous
        target = dlist.pop(0)
        dlist.append( target )
    elif cmd == 2 : # F: move forward, i.e. to next
        target = dlist.pop( len( dlist ) - 1 )
        dlist.insert( 0, target )
    elif cmd == 3 : # R: remove current from list. This forces cd to previous, a
                    # desireable side-effect
        dlist.pop( 0 )
    elif cmd == 4 : # S: select from list
    # The current directory (dlist[0]) is included essentially as ESC.
        for idx in range( len( dlist )) :
            print( '(' + str( idx ) + ')', dlist[ idx ][:-1])
        while True :
            inp = msvcrt.getche()
            if inp.isdigit() :
                inp = int( inp )
                if inp < len( dlist ) :
                    print( '' ) # Print the newline we didn't get from getche.
                    break
            print( ' is out of range' )
    # Select 0 means the current directory and the list is not changed. Otherwise
    # the selected directory is moved to the top of the list. This can be done by
    # either rotating the whole list until the selection is at the head or pop it
    # and insert it to 0. It isn't obvious which would be better for the user but
    # since pop-insert is simpler, it is used.
        if inp > 0 :
            dlist.insert( 0, dlist.pop( inp ))
    
    elif cmd == -1 : # -1: dir is the requested new directory.
    # If it is already in the list then remove it before inserting it at the head.
    # This takes care of both the common case of it having been recently visited
    # and the less common case of user mistakenly requesting current, in which
    # case it is already at the head. Deleting and putting it back is a trivial
    # inefficiency.
        try:
            dlist.pop( indexNoCase( dlist, dir ))
        except ValueError :
            pass
        dlist = dlist[:9] # Control list length by removing older dirs (should be
                          # no more than one).
        dlist.insert( 0, dir ) 
    
    fo.truncate( 0 )
    if cmd != 0 : # C: clear the list
        fo.writelines( dlist )
    
    fo.close()
    exit(0)
    
    0 讨论(0)
提交回复
热议问题