python - change - os chdir('' '')
¿Cómo cambio el directorio(cd) en Python? (14)
cd
como en el comando de shell para cambiar el directorio de trabajo.
¿Cómo cambio el directorio de trabajo actual en Python?
Aquí hay un ejemplo de un administrador de contexto para cambiar el directorio de trabajo. Es más simple que una versión de ActiveState a la que se hace referencia en otro lugar, pero esto hace el trabajo.
Administrador de contexto: 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)
O pruebe el equivalente más conciso (a continuación) , utilizando ContextManager .
Ejemplo
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.
Cambiar el directorio actual del proceso de script es trivial. Creo que la pregunta en realidad es cómo cambiar el directorio actual de la ventana de comandos desde la cual se invoca un script de Python, lo cual es muy difícil. Una secuencia de comandos de Bat en Windows o una secuencia de comandos de Bash en una shell de Bash puede hacer esto con un comando de CD ordinario porque la propia shell es el intérprete. Tanto en Windows como en Linux, Python es un programa y ningún programa puede cambiar directamente el entorno de su padre. Sin embargo, la combinación de un script de shell simple con un script de Python haciendo la mayoría de las cosas difíciles puede lograr el resultado deseado. Por ejemplo, para hacer un comando de cd extendido con historial de recorrido para una revisión hacia atrás / adelante / seleccionar, escribí un script de Python relativamente complejo invocado por un simple script de bat. La lista de recorrido se almacena en un archivo, con el directorio de destino en la primera línea. Cuando el script de python regresa, el script de bat lee la primera línea del archivo y lo convierte en el argumento de cd. El guión completo del bate (menos los comentarios por brevedad) es:
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
El script de python, dSup.py es:
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)
Como ya lo han indicado otros, todas las soluciones anteriores solo cambian el directorio de trabajo del proceso actual. Esto se pierde cuando sales al shell de Unix. Si está desesperado, puede cambiar el directorio shell primario en Unix con este 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")
Más hacia la dirección señalada por Brian y basada en sh (1.0.8+)
from sh import cd, ls
cd(''/tmp'')
print ls()
Puede cambiar el directorio de trabajo con:
import os
os.chdir(path)
Hay dos mejores prácticas a seguir al usar este método:
- Capture la excepción (WindowsError, OSError) en una ruta no válida. Si se lanza la excepción, no realice ninguna operación recursiva, especialmente las destructivas. Operarán en el camino viejo y no en el nuevo.
- Regresa a tu directorio anterior cuando hayas terminado. Esto se puede hacer de una manera segura y excepcional envolviendo su llamada chdir en un administrador de contexto, como lo hizo Brian M. Hunt en su respuesta .
Cambiar el directorio de trabajo actual en un subproceso no cambia el directorio de trabajo actual en el proceso principal. Esto también es cierto para el intérprete de Python. No puede usar os.chdir()
para cambiar el CWD del proceso de llamada.
Si desea realizar una opción como "cd ..", simplemente escriba:
os.chdir ("..")
es el mismo que en Windows cmd: cd .. Por supuesto, la importación es necesaria (p. ej., escríbala como primera línea de su código)
Si está utilizando una versión relativamente nueva de Python, también puede usar un administrador de contexto, como este :
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
ACTUALIZAR
Si prefieres rodar el tuyo:
import os
from contextlib import contextmanager
@contextmanager
def working_directory(directory):
owd = os.getcwd()
try:
os.chdir(directory)
yield directory
finally:
os.chdir(owd)
Yo usaría os.chdir
así:
os.chdir("/path/to/change/to")
Por cierto, si necesita averiguar su ruta actual, use os.getcwd()
.
Más here
y para un uso interactivo fácil, ipython tiene todos los comandos de shell comunes integrados.
cd()
es fácil de escribir usando un generador y un decorador.
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)
Luego, el directorio se revierte incluso después de lanzar una excepción:
os.chdir(''/home'')
with cd(''/tmp''):
# ...
raise Exception("There''s no place like home.")
# Directory is now back to ''/home''.
os.chdir()
es el camino correcto.
os.chdir()
es la versión en Pythonic de cd
.
#import package
import os
#change directory
os.chdir(''my_path'')
#get location
os.getcwd()
Además, es bueno revisar todos los demás comandos útiles en el paquete del sistema operativo aquí https://docs.python.org/3/library/os.html
import os
abs_path = ''C://a/b/c''
rel_path = ''./folder''
os.chdir(abs_path)
os.chdir(rel_path)
Puede usar ambos con os.chdir (abs_path) o os.chdir (rel_path), no es necesario llamar a os.getcwd () para usar una ruta relativa.