Python: execfile do diretório de trabalho de outro arquivo?
-
06-07-2019 - |
Pergunta
Eu tenho algum código que carrega um arquivo de configuração padrão e permite que os usuários forneçam seus próprios arquivos Python como configuração suplementar adicional ou substituições dos padrões:
# foo.py
def load(cfg_path=None):
# load default configuration
exec(default_config)
# load user-specific configuration
if cfg_path:
execfile(cfg_path)
Há um problema, porém: executa execfile()
diretrizes no arquivo especificado por cfg_path
como se fosse no diretório de trabalho de foo.py
, não seu diretório de trabalho. Assim, directivas import
pode falhar se o arquivo cfg_path
faz, digamos, from m import x
onde m
é um módulo no mesmo diretório que cfg_path
.
Como posso execfile()
do diretório de trabalho da sua argumentação, ou de outra forma alcançar um resultado equivalente? Além disso, eu tenho dito que execfile
está obsoleta em Python 3 e que eu deveria estar usando exec
, por isso, se há uma maneira melhor que eu deveria estar fazendo isso, eu sou todo ouvidos.
Nota: Não acho soluções que apenas mudar o diretório de trabalho estão corretas. Isso não vai colocar os módulos no caminho do módulo-lookup do intérprete, tanto quanto eu posso dizer.
Solução
os.chdir permite alterar o trabalho diretório que você deseja (você pode extrair o diretório de trabalho do cfg_path
com os.path.dirname
); certifique-se primeiro obter o diretório atual com os.getcwd se você deseja restaurá-lo quando estiver pronto exec'ing cfg_path
.
Python 3, de fato remover execfile
(em favor de uma sequência onde ler o arquivo, compile
o conteúdo, então exec
-los), mas você não precisa se preocupar com isso, se você está programando atualmente em Python 2.6, uma vez que o 2to3 fonte de tradução fonte lida com tudo isso de forma suave e sem problemas.
Editar : o OP diz, em um comentário, que inicia execfile
um processo separado e não respeita o diretório de trabalho atual. Isso é falso, e aqui está um exemplo mostrando que é:
import os
def makeascript(where):
f = open(where, 'w')
f.write('import os\nprint "Dir in file:", os.getcwd()\n')
f.close()
def main():
where = '/tmp/bah.py'
makeascript(where)
execfile(where)
os.chdir('/tmp')
execfile(where)
if __name__ == '__main__':
main()
A execução deste na minha máquina produz uma saída tais como:
Dir in file: /Users/aleax/stko
Dir in file: /private/tmp
mostrando claramente que execfile
não continuar usando o diretório de trabalho que está definido nas executa execfile
tempo. (Se o arquivo for executado mudanças do diretório de trabalho, que serão refletidas após execfile
retornos - exatamente porque tudo é a ter lugar no mesmo processo).
Assim, quaisquer problemas que o OP ainda está observando são não ligada ao diretório de trabalho atual (é difícil de diagnosticar o que pode realmente ser, sem ver o código e os detalhes exatos dos problemas observados ; -).