Domanda

In alcune delle mie app Django sto usando un file settings_local.py per sovrascrivere le impostazioni diverse da vari ambienti (E.G. Sviluppo, test e produzione).Originariamente ho usato il seguente codice per includere il suo contenuto nel settings.py:

try:
    from settings_local import *
except ImportError:
    sys.stderr.write("The settings_local.py file is missing.\n")
    DEBUG=False
.

Ho recentemente trovato la funzione execfile e passa a qualcosa del genere:

try:
    execfile(path.join(PROJECT_ROOT, "settings_local.py"))
except IOError:
    sys.stderr.write("The settings_local.py file is missing.\n"
    DEBUG=False
.

Entrambi funzionano come previsto, ma sono curioso se mi manca alcun gotcha, e in generale quale approccio è più raccomandato e perché.

È stato utile?

Soluzione

L'utilizzo della funzione execfile comporterà la valutazione del file sorgente Python (.py) ogni volta che viene valutato il file delle impostazioni. Stai eseguendo ogni volta il parser Python. L'utilizzo di import non lo farebbe necessariamente (potrebbe usare il file .pyc). Generalmente la prima volta che esegui un progetto in Python (almeno, CPYTHON) viene compilato su Bytecode e non ricompilato di nuovo. Lo stai rompendo. Questo non è necessariamente un problema, ma dovresti esserne consapevole.

L'utilizzo di execfile comporterà anche tutte le importazioni che potresti avere nel file settings_local.py viene rivalutato nella portata del modulo del file settings.py. L'utilizzo di import * avrebbe incluso tutti gli elementi nell'ambito del modulo settings_local.py. L'effetto netto è lo stesso (tutti gli elementi inclusi nell'ambito del modulo settings_local.py sono inclusi in settings.py) ma il metodo è diverso.

Infine, è normale che i moduli vengano eseguiti come moduli piuttosto che inclusi. È ragionevole per il codice includere le cose come os.path.dirname(__file__). Se un codice è stato utilizzato, lo confonderà in quanto il codice non sarebbe più eseguito nel modulo che l'autore potrebbe essere ragionevolmente previsto.

Nella mia esperienza, le persone usano import non execfile. Django è molto "convention sulla configurazione". Segui la convenzione.

Altri suggerimenti

Un'altra differenza: Execfile ottiene un dizionario del contesto;il contesto globale per impostazione predefinita o un dizionario specificato.Questo potrebbe consentire alcune cose strane

dont_do_this.py:

# Probably not a good thing to do
z=x+1  # an expression that involves an un-defined field
.

Ovviamente,

from dont_do_this import *
.

fallisce.

Tuttavia,

d={'x':1}
execfile( 'dont_do_this.py', d )
.

è OK e risultati in d=={'x':1, 'z':2}

nota che

x=1
execfile( 'dont_do_this.py' )
.

è OK e si traduce nella variabile z aggiunta ai Global.

La prima versione (from settings_local import *) è ciò che tutti si aspettano di vedere.Permetterà anche gli analizzatori di codice a trovare il modulo.

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