it-swarm.com.de

Wie ändere ich das Verzeichnis (CD) in Python?

cd wie im Shell-Befehl zum Ändern des Arbeitsverzeichnisses.

Wie ändere ich das aktuelle Arbeitsverzeichnis in Python?

616
too much php

Sie können das Arbeitsverzeichnis folgendermaßen ändern:

import os

os.chdir(path)

Bei dieser Methode sind zwei bewährte Methoden zu befolgen:

  1. Fangen Sie die Ausnahme (WindowsError, OSError) auf ungültigem Pfad ab. Wenn die Ausnahme ausgelöst wird, führen Sie keine rekursiven Operationen aus, insbesondere keine destruktiven. Sie werden auf dem alten Weg operieren und nicht auf dem neuen.
  2. Kehren Sie zu Ihrem alten Verzeichnis zurück, wenn Sie fertig sind. Dies kann auf ausnahmesichere Weise geschehen, indem Sie Ihren chdir-Aufruf in einen Kontextmanager einbinden, wie es Brian M. Hunt in seine Antwort getan hat.

Durch Ändern des aktuellen Arbeitsverzeichnisses in einem Unterprozess wird das aktuelle Arbeitsverzeichnis im übergeordneten Prozess nicht geändert. Dies gilt auch für den Interpreter Python. Sie können os.chdir() nicht verwenden, um die CWD des aufrufenden Prozesses zu ändern.

690
Michael Labbé

Hier ist ein Beispiel für einen Kontextmanager zum Ändern des Arbeitsverzeichnisses. Es ist einfacher als ein ActiveState-Version , auf das an anderer Stelle verwiesen wird, aber dies erledigt die Aufgabe.

Kontext-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)

Oder probieren Sie das prägnanteres Äquivalent (unten) mit ContextManager .

Beispiel

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.
289
Brian M. Hunt

Ich würde os.chdir folgendermaßen verwenden:

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

Übrigens, wenn Sie Ihren aktuellen Pfad herausfinden müssen, verwenden Sie os.getcwd().

Mehr hier

133
Evan Fosmark

cd() ist mit einem Generator und einem Dekorateur einfach zu schreiben.

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)

Dann wird das Verzeichnis zurückgesetzt, auch nachdem eine Ausnahme ausgelöst wurde:

os.chdir('/home')

with cd('/tmp'):
    # ...
    raise Exception("There's no place like home.")
# Directory is now back to '/home'.
104
cdunn2001

Wenn Sie eine relativ neue Version von Python verwenden, können Sie auch einen Kontextmanager verwenden, z. B. dieser :

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

Wenn Sie es vorziehen, Ihre eigenen zu würfeln:

import os
from contextlib import contextmanager

@contextmanager
def working_directory(directory):
    owd = os.getcwd()
    try:
        os.chdir(directory)
        yield directory
    finally:
        os.chdir(owd)
23
Brian Clapper

Wie bereits von anderen erwähnt, ändern alle oben genannten Lösungen nur das Arbeitsverzeichnis des aktuellen Prozesses. Dies geht verloren, wenn Sie zur Unix-Shell zurückkehren. Wenn Sie verzweifelt sind können ändern Sie das übergeordnete Shell-Verzeichnis unter Unix mit diesem schrecklichen 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")
13
mrdiskodave

os.chdir() ist die pythonische Version von cd.

12
PEZ

os.chdir() ist der richtige Weg.

12

Weiter in die Richtung, auf die Brian hingewiesen hat und die auf sh (1.0.8+) basiert

from sh import cd, ls

cd('/tmp')
print ls()
6

Wenn Sie etwas wie "cd .." ausführen möchten, geben Sie einfach Folgendes ein:

os.chdir ("..")

es ist dasselbe wie in Windows cmd: cd .. Natürlich import os ist erforderlich (z. B. als 1. Zeile Ihres Codes eingeben)

4
D.K
import os

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

os.chdir(abs_path)
os.chdir(rel_path)

Sie können beides mit os.chdir (abs_path) oder os.chdir (rel_path) verwenden. Sie müssen os.getcwd () nicht aufrufen, um einen relativen Pfad zu verwenden.

3
Riccardo D
#import package
import os

#change directory
os.chdir('my_path')

#get location 
os.getcwd()

Es ist auch gut, alle anderen nützlichen Befehle im Betriebssystempaket hier zu überprüfen https://docs.python.org/3/library/os.html

1
shiv

Das Ändern des aktuellen Verzeichnisses des Skriptprozesses ist trivial. Ich denke, die Frage ist eigentlich, wie man das aktuelle Verzeichnis des Befehlsfensters ändert, von dem aus ein Skript python aufgerufen wird, was sehr schwierig ist. Ein Bat-Skript in Windows oder ein Bash-Skript in einer Bash-Shell kann dies mit einem normalen cd-Befehl ausführen, da die Shell selbst der Interpreter ist. Sowohl unter Windows als auch unter Linux ist Python ein Programm, und kein Programm kann die Umgebung seiner Eltern direkt ändern. Die Kombination eines einfachen Shell-Skripts mit einem Python-Skript, das die meisten harten Aufgaben erledigt, kann jedoch das gewünschte Ergebnis erzielen. Um beispielsweise einen erweiterten cd-Befehl mit Traversal-Verlauf für das Zurück-/Vorwärts-/Auswahl-Überarbeiten zu erstellen, habe ich ein relativ komplexes Python -Skript geschrieben, das von einem einfachen Fledermausskript aufgerufen wird. Die Durchsuchungsliste wird in einer Datei gespeichert, wobei sich das Zielverzeichnis in der ersten Zeile befindet. Wenn das Skript python zurückgegeben wird, liest das Skript bat die erste Zeile der Datei und macht sie zum Argument für cd. Das vollständige Fledermaus-Skript (aus Gründen der Kürze ohne Kommentare) lautet:

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

Das python -Skript dSup.py lautet:

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
David McCracken