Existem duas práticas recomendadas a serem seguidas ao usar esse método:
Capture a exceção (WindowsError, OSError) no caminho inválido. Se a exceção for lançada, não execute operações recursivas, especialmente destrutivas. Eles irão operar no caminho antigo e não no novo.
Retorne ao seu diretório antigo quando terminar. Isso pode ser feito de maneira segura contra exceções, envolvendo sua chamada chdir em um gerenciador de contexto, como Brian M. Hunt fez em sua resposta .
Alterar o diretório de trabalho atual em um subprocesso não altera o diretório de trabalho atual no processo pai. Isso também vale para o intérprete Python. Você não pode os.chdir()alterar o CWD do processo de chamada.
A resposta leve e baseada em decorador do cdunn2001 é a abordagem ideal para o Python moderno. A resposta acima demonstra o porquê. Nunca ligue para os.chdir()fora de um gerente de contexto, a menos que você pense que sabe o que está fazendo. ( Você provavelmente não. )
Cecil Curry
6
Essa é a maneira mais fácil em um shell interativo, eu acho. Observe que no Windows, você precisa usar barras, comoos.chdir("C:/path/to/location")
Josiah
A única coisa a ter em atenção é que, se você tornar seu programa python um executável e executá-lo no cron, ele será iniciado no diretório inicial. Portanto, é melhor usar um caminho completo. Isso definitivamente funciona, mas ainda uso caminhos totalmente qualificados em qualquer script que eu possa chamar do Python, porque não há garantia de que isso se aplique fora do próprio programa Python.
precisa saber é o seguinte
310
Aqui está um exemplo de um gerenciador de contexto para alterar o diretório de trabalho. É mais simples que uma versão do ActiveState referida em outro lugar, mas isso faz o trabalho.
Gerenciador 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)
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.
Se você precisar saber em qual diretório você mudou, basta adicionar return selfno final de __enter__. Dessa forma, você pode fazer with cd('foo') as cm:e acessar o diretório anterior comocm.savedPath
Sam F
Observe que há casos em que não é possível retornar ao diretório antigo (aquele armazenado em "savedPath"). Por exemplo, se um processo mais privilegiado executa um processo menos privilegiado, o segundo processo herda o diretório de trabalho dos primeiros processos, mesmo naqueles casos em que o segundo processo não pode entrar nesse diretório de trabalho com seus próprios recursos.
Kai Petzke 11/02/19
140
Eu usaria os.chdirassim:
os.chdir("/path/to/change/to")
A propósito, se você precisar descobrir seu caminho atual, use os.getcwd() .
Brilho! Se o comentário introdutório da resposta aceita fosse injetado nessa resposta, isso seria incomensuravelmente ideal. Ainda assim, a implementação concisa e Pythonically segura desta resposta garante todos os votos positivos que tenho para dar.
Cecil Curry
3
Por que yielde não return? Isso deveria ser um gerador?
EKons 5/08/16
Por favor, comente a relevância do rendimento versus retorno!
NicoBerrogorry
1
@NicoBerrogorry, é um gerador. Veja os documentos em contextlib.contextmanager . Este é um padrão muito útil em Python, que vale a pena aprender.
cdunn2001
25
Se você estiver usando uma versão relativamente nova do Python, também poderá usar um gerenciador 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
ATUALIZAR
Se você preferir lançar seu próprio:
import os
from contextlib import contextmanager
@contextmanagerdef working_directory(directory):
owd = os.getcwd()try:
os.chdir(directory)yield directory
finally:
os.chdir(owd)
Dependências são ruins. O contextlib.contextmanagerdecorador embutido do Python é bom. Veja cdunn2001 's resposta à base de decorador , que seria idealmente a resposta aceita agora.
Cecil Curry
14
Como já apontado por outros, todas as soluções acima alteram apenas o diretório de trabalho do processo atual. Isso é perdido quando você volta para o shell Unix. Se estiver desesperado, você pode alterar o diretório do shell pai no Unix com este hack horrível:
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")
Hack insano e frágil recebe votos obrigatórios. Ninguém deve fazer isso, principalmente com isso "e se o usuário digitar enquanto executa ...", ressalte. Ainda assim, me excita a barba rebelde em mim ao ver que mudar o CWD principal é uma espécie de, mas não realmente viável. Upvotes! Upvotes para todos!
Se você usa o Spyder e adora a GUI, pode simplesmente clicar no botão de pasta no canto superior direito da tela e navegar pelas pastas / diretórios que deseja como diretório atual. Depois disso, você pode ir para a guia explorador de arquivos da janela no spyder IDE e pode ver todos os arquivos / pastas presentes lá. Para verificar seu diretório de trabalho atual, acesse o console do Spyder IDE e digite
pwd
ele imprimirá o mesmo caminho que você selecionou anteriormente.
Alterar o diretório atual do processo de script é trivial. Eu acho que a questão é realmente como alterar o diretório atual da janela de comando a partir da qual um script python é chamado, o que é muito difícil. Um script Bat no Windows ou um script Bash em um shell Bash pode fazer isso com um comando cd comum, porque o próprio shell é o intérprete. No Windows e no Linux, Python é um programa e nenhum programa pode alterar diretamente o ambiente de seus pais. No entanto, a combinação de um script de shell simples com um script Python fazendo a maioria das coisas difíceis pode alcançar o resultado desejado. Por exemplo, para criar um comando cd estendido com histórico de travessia para revisar para trás / para frente / selecionar, escrevi um script Python relativamente complexo, invocado por um simples script bat. A lista de travessia é armazenada em um arquivo, com o diretório de destino na primeira linha. Quando o script python retorna, o script bat lê a primeira linha do arquivo e o torna o argumento para cd. O script bastão completo (menos comentários por brevidade) é:
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 andreturn to previous.
echo -S = select from list.
echo -H,-h,?= help.
echo .= make window title current directory.
echo Anythingelse= target directory.
goto done
:doCd
%~dp0dSup.py %1for/F %%d in(%~dp0dSupList )do(
cd %%d
if errorlevel 1(%~dp0dSup.py -R )
goto cdDone
):cdDone
title %CD%:done
O script python, dSup.py é:
import sys, os, msvcrt
def indexNoCase ( slist, s ):for idx in range( len( slist )):if slist[idx].upper()== s.upper():return idx
raiseValueError# .........main process ...................if len( sys.argv )<2:
cmd =1# No argument defaults to -B, the most common operationelif 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])whileTrue:
inp = msvcrt.getche()if inp.isdigit():
inp = int( inp )if inp < len( dlist ):print('')# Print the newline we didn't get from getche.breakprint(' 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 ))exceptValueError: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)
Embora seja uma boa resposta, o OP selecionou uma resposta que diz que não se trata de alterar o CWD do processo pai. Isso esclarece qualquer possível confusão sobre o que a pergunta significa.
the Tin Man
Para Tin Man - essa resposta foi selecionada antes de eu postar minha sugestão. Eu acho que as respostas abrangentes podem ter sido confusas. O cd dentro de um determinado processo (ou seja, um script python) é tão simples que não sei por que alguém perguntaria.
David McCracken
1
Na verdade, essa resposta foi selecionada anos atrás. Se não fosse apropriado, teria sido chamado várias vezes desde então.
the Tin Man
Eu acho que essa confusão permanece. Mais recentemente, a questão "simulando o comando" cd "do linux em python e persistindo a alteração do diretório após a saída do programa [duplicado]" foi descartada como tendo sido respondida aqui, mas, na verdade, essa questão não é abordada pela resposta selecionada. Minha sugestão é para o Windows, mas os problemas são os mesmos no Linux.
os.chdir(os.path.join(os.path.abspath(os.path.curdir),u'subfolder'))
- ou?os.getcwd()
Respostas:
Você pode alterar o diretório de trabalho com:
Existem duas práticas recomendadas a serem seguidas ao usar esse método:
Alterar o diretório de trabalho atual em um subprocesso não altera o diretório de trabalho atual no processo pai. Isso também vale para o intérprete Python. Você não pode
os.chdir()
alterar o CWD do processo de chamada.fonte
os.chdir()
fora de um gerente de contexto, a menos que você pense que sabe o que está fazendo. ( Você provavelmente não. )os.chdir("C:/path/to/location")
Aqui está um exemplo de um gerenciador de contexto para alterar o diretório de trabalho. É mais simples que uma versão do ActiveState referida em outro lugar, mas isso faz o trabalho.
Gerenciador de Contexto:
cd
Ou tente o equivalente mais conciso (abaixo) , usando o ContextManager .
Exemplo
fonte
return self
no final de__enter__
. Dessa forma, você pode fazerwith cd('foo') as cm:
e acessar o diretório anterior comocm.savedPath
Eu usaria
os.chdir
assim:A propósito, se você precisar descobrir seu caminho atual, use
os.getcwd()
.Mais aqui
fonte
cd()
é fácil escrever usando um gerador e um decorador.Em seguida, o diretório é revertido mesmo depois que uma exceção é lançada:
fonte
try/finally
).yield
e nãoreturn
? Isso deveria ser um gerador?Se você estiver usando uma versão relativamente nova do Python, também poderá usar um gerenciador de contexto, como este :
ATUALIZAR
Se você preferir lançar seu próprio:
fonte
contextlib.contextmanager
decorador embutido do Python é bom. Veja cdunn2001 's resposta à base de decorador , que seria idealmente a resposta aceita agora.Como já apontado por outros, todas as soluções acima alteram apenas o diretório de trabalho do processo atual. Isso é perdido quando você volta para o shell Unix. Se estiver desesperado, você pode alterar o diretório do shell pai no Unix com este hack horrível:
fonte
os.chdir()
é o caminho certo.fonte
os.chdir()
é a versão Pythonic decd
.fonte
Você pode usar os.chdir (abs_path) ou os.chdir (rel_path), não há necessidade de chamar os.getcwd () para usar um caminho relativo.
fonte
Mais adiante, na direção apontada por Brian e baseada em sh (1.0.8+)
fonte
Se você deseja executar algo como a opção "cd ..", digite:
os.chdir ("..")
é o mesmo que no Windows cmd: cd. É claro que o import os é necessário (por exemplo, digite-o como a primeira linha do seu código)
fonte
Se você usa o Spyder e adora a GUI, pode simplesmente clicar no botão de pasta no canto superior direito da tela e navegar pelas pastas / diretórios que deseja como diretório atual. Depois disso, você pode ir para a guia explorador de arquivos da janela no spyder IDE e pode ver todos os arquivos / pastas presentes lá. Para verificar seu diretório de trabalho atual, acesse o console do Spyder IDE e digite
ele imprimirá o mesmo caminho que você selecionou anteriormente.
fonte
Alterar o diretório atual do processo de script é trivial. Eu acho que a questão é realmente como alterar o diretório atual da janela de comando a partir da qual um script python é chamado, o que é muito difícil. Um script Bat no Windows ou um script Bash em um shell Bash pode fazer isso com um comando cd comum, porque o próprio shell é o intérprete. No Windows e no Linux, Python é um programa e nenhum programa pode alterar diretamente o ambiente de seus pais. No entanto, a combinação de um script de shell simples com um script Python fazendo a maioria das coisas difíceis pode alcançar o resultado desejado. Por exemplo, para criar um comando cd estendido com histórico de travessia para revisar para trás / para frente / selecionar, escrevi um script Python relativamente complexo, invocado por um simples script bat. A lista de travessia é armazenada em um arquivo, com o diretório de destino na primeira linha. Quando o script python retorna, o script bat lê a primeira linha do arquivo e o torna o argumento para cd. O script bastão completo (menos comentários por brevidade) é:
O script python, dSup.py é:
fonte