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.

È stato utile?

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 ; -).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top