在我的一些Django应用程序中,我使用settings_local.py
文件来覆盖各种环境(例如开发,测试和生产)上不同的设置。我最初使用以下代码将其内容包含在settings.py
:
try:
from settings_local import *
except ImportError:
sys.stderr.write("The settings_local.py file is missing.\n")
DEBUG=False
我最近找到了execfile
功能,并改为:
try:
execfile(path.join(PROJECT_ROOT, "settings_local.py"))
except IOError:
sys.stderr.write("The settings_local.py file is missing.\n"
DEBUG=False
两者都按预期工作,但我很好奇我是否遗漏了任何陷阱,一般来说,更推荐哪种方法以及原因。
答案 0 :(得分:14)
每次评估设置文件时,使用execfile
函数将导致评估Python源文件(.py)。您每次都在执行Python解析器。使用import
不一定会这样做(可能使用.pyc文件)。通常,第一次在Python中运行项目(至少是cPython)时,它会被编译为字节码而不会再次重新编译。你打破了。这不一定是个问题,但你应该知道它。
使用execfile
也会导致在settings_local.py
文件的模块范围内重新评估settings.py
文件中的所有导入。使用import *
会包含settings_local.py
模块范围内的所有项目。净效果是相同的(settings_local.py
模块范围中包含的所有项目都包含在settings.py
中),但方法不同。
最后,将模块作为模块执行而不是包含在内是正常的。代码包含os.path.dirname(__file__)
等内容是合理的。如果任何代码确实使用了这个,那么你会混淆它,因为代码将不再在作者可能合理预期的模块中执行。
根据我的经验,人们使用import
而不是execfile
。 Django非常“超越配置”。遵循惯例。
答案 1 :(得分:8)
另一个区别:execfile获取上下文字典;默认情况下的全局上下文或 指定的字典。这可能会带来一些奇怪的东西
dont_do_this.py
:
# Probably not a good thing to do
z=x+1 # an expression that involves an un-defined field
显然,
from dont_do_this import *
失败。
然而,
d={'x':1}
execfile( 'dont_do_this.py', d )
没问题,结果为d=={'x':1, 'z':2}
请注意
x=1
execfile( 'dont_do_this.py' )
没问题,导致变量z
被添加到全局变量中。
答案 2 :(得分:2)
第一个版本(from settings_local import *
)是每个人都希望看到的。它还可以让代码分析器找到模块。