Python: execfile dalla directory di lavoro di altri file?
-
06-07-2019 - |
Domanda
Ho del codice che carica un file di configurazione predefinito e quindi consente agli utenti di fornire i propri file Python come configurazione aggiuntiva aggiuntiva o sostituzioni dei valori predefiniti:
# foo.py
def load(cfg_path=None):
# load default configuration
exec(default_config)
# load user-specific configuration
if cfg_path:
execfile(cfg_path)
Tuttavia, c'è un problema: execfile ()
esegue le direttive nel 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
, ad esempio, da m import x
dove m
è un modulo nella stessa directory di cfg_path
.
Come posso execfile ()
dalla directory di lavoro del suo argomento, o altrimenti ottenere 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 farlo, io Sono tutte orecchie.
Nota: non credo che le soluzioni che cambiano semplicemente la directory di lavoro siano corrette. Ciò non metterà quei moduli sul percorso di ricerca dei moduli dell'interprete, per quanto ne so.
Soluzione
os.chdir ti consente di cambiare il funzionamento directory come desideri (puoi estrarre la directory di lavoro di cfg_path
con os.path.dirname
); assicurati di ottenere prima la directory corrente con os.getcwd se si desidera ripristinarlo al termine dell'esecuzione di cfg_path
.
Python 3 rimuove effettivamente execfile
(a favore di una sequenza in cui leggi il file, compila
il contenuto, quindi exec
) , ma non devi preoccuparti di questo, se stai attualmente codificando in Python 2.6, poiché 2to3 la traduzione da fonte a fonte si occupa di tutto ciò senza intoppi e senza soluzione di continuità.
Modifica : l'OP afferma, in un commento, che execfile
avvia un processo separato e non rispetta la directory di lavoro corrente. Questo è falso, ed ecco un esempio che mostra 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 sul mio computer produce output come:
Dir in file: /Users/aleax/stko
Dir in file: /private/tmp
mostra chiaramente che execfile
continua a continuare a utilizzare la directory di lavoro impostata al momento dell'esecuzione di execfile
. (Se il file eseguito cambia la directory di lavoro, ciò si rifletterà dopo che esegui
- esattamente perché tutto sta svolgendo lo stesso processo!).
Quindi, qualsiasi problema che l'OP sta ancora osservando è non legato alla directory di lavoro corrente (è difficile diagnosticare ciò che potrebbero effettivamente essere, senza vedere il codice e i dettagli esatti dei problemi osservati ; -).