Pregunta

Tengo un código que carga un archivo de configuración predeterminado y luego permite a los usuarios proporcionar sus propios archivos de Python como configuración suplementaria adicional o anulación de los valores predeterminados:

# foo.py

def load(cfg_path=None):
    # load default configuration
    exec(default_config)

    # load user-specific configuration
    if cfg_path:
        execfile(cfg_path)

Sin embargo, hay un problema: execfile () ejecuta directivas en el archivo especificado por cfg_path como si estuviera en el directorio de trabajo de foo.py , no es su propio directorio de trabajo. Por lo tanto, las directivas import pueden fallar si el archivo cfg_path hace, por ejemplo, from m import x donde m es un módulo en el mismo directorio que cfg_path .

¿Cómo execfile () del directorio de trabajo de su argumento, o de lo contrario logro un resultado equivalente? Además, me han dicho que execfile está en desuso en Python 3 y que debería usar exec , así que si hay una mejor manera de hacerlo, yo soy todo oídos.

Nota: no creo que las soluciones que simplemente cambian el directorio de trabajo sean correctas. Eso, por lo que puedo decir, no colocará esos módulos en la ruta de búsqueda de módulos del intérprete.

¿Fue útil?

Solución

os.chdir le permite cambiar el funcionamiento directorio como desee (puede extraer el directorio de trabajo de cfg_path con os.path.dirname ); asegúrese de obtener primero el directorio actual con os.getcwd si desea restaurarlo cuando haya terminado de ejecutar cfg_path .

Python 3 elimina de hecho execfile (a favor de una secuencia en la que lea el archivo, compile el contenido, luego exec ) , pero no debe preocuparse por eso, si actualmente está codificando en Python 2.6, ya que 2to3 la traducción de fuente a fuente se ocupa de todo esto sin problemas.

Editar : el OP dice, en un comentario, que execfile inicia un proceso separado y no respeta el directorio de trabajo actual. Esto es falso, y aquí hay un ejemplo que muestra que es:

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

Ejecutar esto en mi máquina produce resultados como:

Dir in file: /Users/aleax/stko
Dir in file: /private/tmp

muestra claramente que execfile sigue usando el directorio de trabajo que está configurado en el momento en que se ejecuta execfile . (Si el archivo ejecutado cambia el directorio de trabajo, eso se reflejará después de que execfile regrese, ¡exactamente porque todo está teniendo lugar en el mismo proceso!).

Entonces, cualquier problema que el OP todavía esté observando no está vinculado al directorio de trabajo actual (es difícil diagnosticar cuáles pueden ser realmente, sin ver el código y los detalles exactos de los problemas observados ;-).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top