导入和execfile之间的区别

Old*_*zer 5 import python-import execfile python-2.7

我有一个utils.py包含名为的函数的文件f1()

通过另一个Python脚本,我可以import utilsexecfile('utils.py')可以访问f1()。两种方法有什么区别?

jez*_*jez 5

有很多差异,但是从您的角度来看,最重要的可能是import使您可以更好地控制utils.py最终定义对象的名称空间。

让我们考虑的三个变体import。第一个是您询问的内容:

import utils
utils.f1()
Run Code Online (Sandbox Code Playgroud)

utils是唯一添加到您的工作空间中的符号- f1基本工作空间中预先存在的任何内容都不会被覆盖,并且如果没有,f1()则将不会被识别。对于要维护的代码,我非常喜欢这种导入方式,因为它使我可以轻松地在源文件中搜索其依赖的所有位置utils

但是,如果utils.f1()每次都说得太冗长,则可以这样做:

from utils import f1
f1()
Run Code Online (Sandbox Code Playgroud)

现在,如果您说f1()它将调用utils.f1(),因为这是您现在与f1工作空间中的名称关联的代码对象。现在,要稍微了解一下代码在utils模块上所处的位置,会有些困难。但是,至少这种类型的import语句使您可以精确控制哪些符号被导入,哪些没有。您甚至可以在此过程中重命名符号:

from utils import f1 as EffOne
EffOne()  
Run Code Online (Sandbox Code Playgroud)

最后,您可以选择完全失去对名称空间的控制:

from utils import *
Run Code Online (Sandbox Code Playgroud)

现在,谁知道已经导入了什么符号:基本上,所有utils必须提供给世界的东西(或者,如果utils开发人员麻烦地指定一个__all__属性,那么那里列出的所有东西)。import *如果有的话,我建议您仅用于快速编程。

实际上,这是execfile从名称空间角度最接近的导入样式:execfile('utils.py')所做的操作与from utils import *utilswilly-nilly 定义的所有符号都转储到您的工作区中的功能相同。一个微小的区别是,execfile即使__all__定义了符号,它也不会限制自己,实际上,__all__符号本身只会与其他所有东西一起丢在您的腿上。

除了名称空间外,from utils import *和之间还有很多区别execfile('utils.py')。一个正在缓存:第二次import调用utils将非常快(不会重新运行代码),但是第二次调用execfile('utils.py')可能会花费与第一次调用一样长的时间,因为它将重新运行代码。另外,内部可能存在某些代码(通常是测试代码)utils.pyutils作者不希望在导入时运行,而当通过执行文件时才希望运行execfile。此类代码放在if __name__ == '__main__':子句中。