Comment changer le répertoire (cd) en Python?

cd comme dans la commande shell pour changer le répertoire de travail.

Comment changer le répertoire de travail actuel en Python?

521
demandé sur kvmahesh 2009-01-10 23:28:16

13 réponses

Vous pouvez changer le répertoire de travail avec:

import os

os.chdir(path)

il y a deux pratiques exemplaires à suivre lorsqu'on utilise cette méthode:

  1. intercepter l'exception (WindowsError, OSError) sur le chemin d'accès non valide. Si l'exception est lancée, ne pas effectuer d'opérations récursives, en particulier destructives. Ils exercent sur l'ancien chemin et non la nouvelle.
  2. retournez à votre ancien répertoire lorsque vous avez terminé. Ce peut être fait d'une manière exceptionnellement sûre en enveloppant votre appel chdir dans un gestionnaire de contexte, comme Brian M. Hunt l'a fait dans sa réponse .

changer le répertoire de travail courant dans un sous-processus ne change pas le répertoire de travail courant dans le processus parent. C'est également vrai pour l'interpréteur Python. Vous ne pouvez pas utiliser os.chdir() pour changer le CWD du processus d'appel.

567
répondu Michael Labbé 2017-06-29 03:53:23

voici un exemple de gestionnaire de contexte pour changer le répertoire de travail. Il est plus simple qu'une version activée mentionnée ailleurs, mais cela permet de faire le travail.

Gestionnaire De Contexte: 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)

Ou d'essayer de la plus concis équivalent(ci-dessous) , à l'aide de ContextManager .

exemple

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.
260
répondu Brian M. Hunt 2017-05-23 12:26:42

j'utiliserais os.chdir comme ceci:

os.chdir("/path/to/change/to")

en passant, si vous avez besoin de calculer votre chemin actuel, utilisez os.getcwd() .

plus ici

126
répondu Evan Fosmark 2017-10-24 09:29:58

cd() est facile à écrire à l'aide d'un générateur et d'un décorateur.

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)

ensuite, le répertoire est inversé même après qu'une exception est lancée:

os.chdir('/home')

with cd('/tmp'):
    # ...
    raise Exception("There's no place like home.")
# Directory is now back to '/home'.
85
répondu cdunn2001 2015-03-15 18:20:17

si vous utilisez une version relativement nouvelle de Python, vous pouvez également utiliser un gestionnaire de contexte, tel que celui-ci :

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

mise à JOUR

si vous préférez rouler le vôtre:

import os
from contextlib import contextmanager

@contextmanager
def working_directory(directory):
    owd = os.getcwd()
    try:
        os.chdir(directory)
        yield directory
    finally:
        os.chdir(owd)
22
répondu Brian Clapper 2016-05-23 17:21:18

os.chdir() est le bon chemin.

11
répondu Federico A. Ramponi 2009-01-10 20:34:53

comme déjà souligné par d'autres, toutes les solutions ci-dessus ne font que changer le répertoire de travail du processus en cours. C'est perdu lorsque vous sortez de L'interpréteur de commandes Unix. Si desperate vous peut changer le répertoire shell parent sur Unix avec cet 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")
11
répondu mrdiskodave 2014-09-14 19:41:00

os.chdir() est la version pythonique de cd .

11
répondu PEZ 2016-01-25 20:34:37

plus loin dans la direction indiqué par Brian et basé sur sh (1.0.8+)

from sh import cd, ls

cd('/tmp')
print ls()
6
répondu Yauhen Yakimovich 2013-07-02 13:50:24

si vous souhaitez effectuer quelque chose comme" cd.."option, tapez juste:

os.chdir("..")

il est identique à celui de Windows cmd: cd.. Bien sûr, importation os est nécessaire (E. g tapez-le comme première ligne de votre code)

4
répondu D.K 2016-10-10 18:05:47

changer le répertoire courant du processus de script est trivial. Je pense que la question Est en fait de savoir comment changer le répertoire courant de la fenêtre de commande à partir de laquelle un script python est invoqué, ce qui est très difficile. Un script Bat dans Windows ou un script Bash dans un shell Bash peut le faire avec une commande cd ordinaire parce que le shell lui-même est l'interpréteur. Sous Windows et Linux, Python est un programme et aucun programme ne peut modifier directement l'environnement de son parent. Cependant, l' la combinaison d'un script shell simple avec un script Python faisant la plupart des choses difficiles peut atteindre le résultat désiré. Par exemple, pour faire une commande de cd prolongée avec historique transversal pour backward/forward/select revisit, j'ai écrit un script Python relativement complexe invoqué par un simple script bat. La liste transversale est stockée dans un fichier, avec le répertoire cible sur la première ligne. Quand le script python retourne, le script bat lit la première ligne du fichier et en fait l'argument du cd. Le script bat complet (moins les commentaires pour la brièveté) est:

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

le script python, dSup.py est:

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
répondu David McCracken 2016-03-07 17:23:56
#import package
import os

#change directory
os.chdir('my_path')

#get location 
os.getcwd()

aussi, il est bon de vérifier toutes les autres commandes utiles dans le paquet OS ici https://docs.python.org/3/library/os.html

0
répondu shiv 2018-09-14 16:33:36

et pour une utilisation interactive facile, ipython a toutes les commandes shell communes intégrées.

-5
répondu Autoplectic 2009-01-10 21:15:09