Python:'importação' vs execfile
-
13-12-2019 - |
Pergunta
Em alguns dos meus Django apps que eu estou usando um settings_local.py
arquivo para substituir as configurações que são diferentes em vários ambientes (e.g.desenvolvimento, teste e produção).Eu tenho originalmente utilizado o seguinte código para incluir o seu conteúdo na settings.py
:
try:
from settings_local import *
except ImportError:
sys.stderr.write("The settings_local.py file is missing.\n")
DEBUG=False
Eu tenho encontrado recentemente o execfile
função e mudar para 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 trabalham como se pretende, mas eu estou curioso para saber se eu estou faltando alguma dicas, e em geral, a abordagem é mais recomendado e por quê.
Solução
Usando execfile
função fará com que a avaliação do Python arquivo de origem.py) cada vez que o arquivo de configurações é avaliada.Está a executar o Python parser de cada vez.Usando import
não necessariamente fazer isso (pode utilizar .pyc arquivo).Geralmente a primeira vez que você executar um projeto em Python (pelo menos, cPython) é compilada para um bytecode e não recompilado novamente.Você está quebrar.Isso não é necessariamente um problema, mas você deve estar ciente disso.
Usando execfile
também resultará em todas as importações você pode ter no settings_local.py
arquivo a ser re-avaliada no âmbito do módulo de settings.py
arquivo.Usando import *
teria incluído todos os itens no settings_local.py
âmbito do módulo.O efeito líquido é o mesmo (todos os itens incluídos na settings_local.py
âmbito do módulo estão incluídos no settings.py
), mas o método é diferente.
Finalmente, é normal que os módulos sejam executadas como módulos, ao invés de incluir incluído.É razoável que o código para incluir coisas tais como os.path.dirname(__file__)
.Se qualquer código de usar isso, você poderia confundi-lo como o código deixaria de ser executado no módulo que o autor pode razoavelmente esperar.
Na minha experiência, as pessoas usam import
não execfile
.Django é muito "convenção sobre configuração".Siga a convenção.
Outras dicas
Outra diferença:execfile fica um contexto de dicionário;o contexto global por padrão ou um dicionário especificado.Isso pode permitir que algumas coisas estranhas
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 *
falha.
No entanto,
d={'x':1}
execfile( 'dont_do_this.py', d )
é OK e resulta em d=={'x':1, 'z':2}
Note que
x=1
execfile( 'dont_do_this.py' )
é OK e resultados na variável z
sendo adicionados ao globals.
A primeira versão (from settings_local import *
) é o que todos deveriam esperar para ver.Ele também irá permitir que o código de analisadores de encontrar o módulo.