2009-11-28 10 views
7

ho un po 'di codice che carica un file di configurazione di default e quindi consente agli utenti di fornire i propri file Python come ulteriore configurazione supplementare o le sostituzioni delle impostazioni predefinite:Python: execfile dalla directory di lavoro di altri file?

# foo.py 

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

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

C'è un problema, però: execfile() esegue direttive il file specificato da cfg_path come se fosse nella directory di lavoro di foo.py, non la propria directory di lavoro. Pertanto, le direttive import potrebbero non riuscire se il file cfg_path fa, ad esempio, from m import x dove m è un modulo nella stessa directory di cfg_path.

Come faccio a execfile() dalla directory di lavoro del suo argomento, o altrimenti raggiungere un risultato equivalente? Inoltre, mi è stato detto che execfile è deprecato in Python 3 e che dovrei usare exec, quindi se c'è un modo migliore che dovrei fare, sono tutto orecchie.

Nota: Non penso che le soluzioni che cambiano semplicemente la directory di lavoro siano corrette. Ciò non metterà quei moduli sul percorso di ricerca del modulo dell'interprete, per quanto posso dire.

risposta

7

os.chdir consente di modificare la directory di lavoro come si desidera (è possibile estrarre la directory di lavoro di cfg_path con os.path.dirname); assicurati di avere prima la directory corrente con os.getcwd se vuoi ripristinarla quando hai terminato exec'ing cfg_path.

Python 3 effettivamente rimuovere execfile (a favore di una sequenza in cui si legge il file, compile il contenuto, poi li exec), ma non è necessario preoccuparsi di questo, se si sta attualmente codifica in Python 2.6, dal momento che la traduzione da sorgente a sorgente di 2to3 si occupa di tutto ciò in modo fluido e senza interruzioni.

Modifica: l'OP dice, in un commento, che execfile avvia un processo separato e non rispetta la directory di lavoro corrente. Questo è falso, ed ecco un esempio dimostrando che è:

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

L'esecuzione di questo sulla mia macchina produce un output come ad esempio:

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

mostrando chiaramente che execfilefa continuare ad usare la directory di lavoro che è impostato al momento execfile eseguito. (Se il file eseguito cambia la directory di lavoro, questo verrà riflesso dopo i ritorni execfile - esattamente perché tutto è che si svolge nello stesso processo!).

Quindi, qualsiasi problema l'OP sta ancora osservando sono non legato alla directory di lavoro corrente (è difficile da diagnosticare ciò che essi possono effettivamente essere, senza vedere il codice e la politica relativa ai problemi osservati ;-).

+0

Grazie per la risposta. Sfortunatamente, questo non sembra funzionare per me. 'execfile()' sembra che stia avviando un processo completamente nuovo con la propria directory di lavoro, che non è la stessa di quella da cui lancio. –

+0

No, @Kyle, 'execfile' non avvia un processo separato, e ** fa ** rispetta la directory di lavoro corrente. Modifica la mia risposta per mostrare un semplice esempio dimostrando che ti stai sbagliando. –

Problemi correlati