在我的一些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

两者都按预期工作,但我很好奇我是否错过了任何gotchas,一般来说哪种方法更推荐以及为什么。

有帮助吗?

解决方案

使用 execfile 函数将导致每次评估设置文件时对Python源文件(.py)进行评估。您每次都在执行Python解析器。使用 import 不一定会这样做(可能会使用。pyc文件)。通常,当您第一次在Python中运行项目(至少是cPython)时,它会被编译为字节码,而不会再次重新编译。你打破了它。这不一定是一个问题,但你应该意识到这一点。

使用 execfile 也将导致您可能在 settings_local.pysettings.py 档案。使用 import * 将包括所有项目在 settings_local.py 模块范围。净效果是相同的(所有项目包括在 settings_local.py 模块范围包括在 settings.py)但方法不同。

最后,模块作为模块执行而不是包含是正常的。代码包含以下内容是合理的 os.path.dirname(__file__).如果有任何代码确实使用了它,你会混淆它,因为代码将不再在作者可能合理预期的模块中执行。

根据我的经验,人们使用 import 不是 execfile.Django非常"约定而不是配置"。遵循惯例。

其他提示

另一个区别: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' )
.

是可以的,并导致可变的世代odicetagcode添加到全局。

第一个版本(from settings_local import *)是每个人都希望看到的。它还会让代码分析器找到模块。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top