Pregunta

En algunas de mis aplicaciones Django estoy usando un settings_local.py archivo para anular configuraciones que son diferentes en varios entornos (p. ej.desarrollo, prueba y producción).Originalmente he usado el siguiente código para incluir su contenido en el settings.py:

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

Recientemente encontré el execfile función y cambió a algo como:

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

Ambos funcionan según lo previsto, pero tengo curiosidad por saber si me falta algún truco y, en general, qué enfoque es más recomendado y por qué.

¿Fue útil?

Solución

Usando execfile La función dará como resultado la evaluación del archivo fuente de Python (.py) cada vez que se evalúe el archivo de configuración.Estás ejecutando el analizador Python cada vez.Usando import No necesariamente haría esto (podría usar el archivo .pyc).Generalmente, la primera vez que ejecuta un proyecto en Python (al menos, cPython), se compila en código de bytes y no se vuelve a compilar.Estás rompiendo eso.Esto no es necesariamente un problema, pero debes ser consciente de ello.

Usando execfile también resultará en todas las importaciones que pueda tener en el settings_local.py archivo que se está reevaluando en el alcance del módulo del settings.py archivo.Usando import * habría incluido todos los elementos en el settings_local.py alcance del módulo.El efecto neto es el mismo (todos los elementos incluidos en settings_local.py El alcance del módulo está incluido en settings.py) pero el método es diferente.

Finalmente, es normal que los módulos se ejecuten como módulos en lugar de incluirse.Es razonable que el código incluya cosas como os.path.dirname(__file__).Si algún código usara esto, lo confundiría ya que el código ya no se ejecutaría en el módulo que el autor podría haber esperado razonablemente.

En mi experiencia, la gente usa import no execfile.Django es en gran medida "convención sobre configuración".Sigue la convención.

Otros consejos

Otra diferencia:execfile obtiene un diccionario de contexto;El contexto global por defecto o un diccionario especificado.Esto podría permitir algunas cosas extrañas.

dont_do_this.py:

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

Obviamente,

from dont_do_this import *

falla.

Sin embargo,

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

está bien y da como resultado d=={'x':1, 'z':2}

Tenga en cuenta que

x=1
execfile( 'dont_do_this.py' )

está bien y da como resultado la variable z siendo agregado a los globales.

La primera versión (from settings_local import *) es lo que todos esperarían ver.También permitirá que los analizadores de código encuentren el módulo.

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