简体   繁体   English

Python:'import *'vs execfile

[英]Python: 'import *' vs execfile

In some of my Django apps I'm using a settings_local.py file to override settings that are different on various environments (eg development, test and production). 在我的一些Django应用程序中,我使用settings_local.py文件来覆盖各种环境(例如开发,测试和生产)上不同的设置。 I have originally used the following code to include its contents in the settings.py : 我最初使用以下代码将其内容包含在settings.py

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

I have recently found the execfile function and switched to something like: 我最近发现了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

Both work as intended, but I'm curious whether I'm missing any gotchas, and in general which approach is more recommended and why. 两者都按预期工作,但我很好奇我是否遗漏了任何陷阱,一般来说哪种方法更值得推荐以及为什么。

Using execfile function will result in the evaluation of the Python source file (.py) every time the settings file is evaluated. 每次评估设置文件时,使用execfile函数将导致评估Python源文件(.py)。 You are executing the Python parser each time. 您每次都在执行Python解析器。 Using import wouldn't necessarily do this (might use the .pyc file). 使用import不一定会这样做(可能使用.pyc文件)。 Generally the first time you run a project in Python (at least, cPython) it gets compiled to bytecode and not recompiled again. 通常,第一次在Python中运行项目(至少是cPython)时,它会被编译为字节码而不会再次重新编译。 You are breaking that. 你打破了。 This isn't necessarily a problem, but you should be aware of it. 这不一定是个问题,但你应该意识到这一点。

Using execfile will also result in all of the imports you may have in the settings_local.py file being re-evaluated in the module scope of the settings.py file. 使用execfile也将导致所有你可能有进口量的settings_local.py文件中的模块范围进行重新评估settings.py文件。 Using import * would have included all items in the settings_local.py module scope. 使用import *会包含settings_local.py模块范围中的所有项目。 The net effect is the same (all items included in settings_local.py module scope are included in settings.py ) but the method is different. 净效果是相同的( settings_local.py模块范围中包含的所有项目都包含在settings.py )但方法不同。

Finally, it's normal for modules to be executed as modules rather than included. 最后,模块作为模块执行而不是包含在内是正常的。 It is reasonable for code to include things such as os.path.dirname(__file__) . 代码包含os.path.dirname(__file__)等内容是合理的。 If any code did use this, you would confuse it as the code would no longer be executing in the module that the author might reasonably have expected. 如果任何代码确实使用了这个,你会混淆它,因为代码将不再在作者可能合理预期的模块中执行。

In my experience, people use import not execfile . 根据我的经验,人们使用import而不是execfile Django is very much 'convention over configuration'. Django非常“超越配置”。 Follow the convention. 遵循惯例。

Another difference: execfile gets a context dictionary; 另一个区别:execfile获取上下文字典; the global context by default or a specified dictionary. 默认情况下的全局上下文或指定的字典。 This could allow some strange things 这可能会让一些奇怪的事情发生

dont_do_this.py : dont_do_this.py

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

Obviously, 明显,

from dont_do_this import *

fails. 失败。

However, 然而,

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

is OK and results in d=={'x':1, 'z':2} 没问题,导致d=={'x':1, 'z':2}

Note that 注意

x=1
execfile( 'dont_do_this.py' )

is OK and results in the variable z being added to the globals. 没问题,导致变量z被添加到全局变量中。

The first version ( from settings_local import * ) is what everyone would expect to see. 第一个版本( from settings_local import * )是每个人都希望看到的。 It will also let code analyzers find the module. 它还可以让代码分析器找到模块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM