import和execfile之间的区别

时间:2014-12-17 01:35:27

标签: python-2.7 import python-import execfile

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

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

1 个答案:

答案 0 :(得分:4)

存在许多差异,但从您的角度来看,最重要的可能是import可以让您更好地控制utils.py中定义的对象所在的命名空间。

让我们考虑import上的三个变体。第一个是你问的问题:

import utils
utils.f1()

utils是已添加到工作区的唯一符号 - 基础工作区中任何预先存在的f1都不会被覆盖,如果没有,则{{1}本身不会被承认。对于我打算维护的代码,我更喜欢这种导入方式,因为它使我可以轻松地搜索我的源文件以查找它依赖于f1()的所有位置。

但如果每次说utils都过于冗长,那么你可以这样做:

utils.f1()

现在,如果您说from utils import f1 f1() 将调用f1(),因为这是您现在与工作区中的名称utils.f1()关联的代码对象。现在稍微难以概述代码依赖于f1模块的位置。但至少这种类型的utils语句可以精确控制导入的符号和不导入的符号。您甚至可以在此过程中重命名符号:

import

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

from utils import f1 as EffOne
EffOne()  

现在,谁知道导入了哪些符号:基本上from utils import * 必须为全世界提供的所有内容(或者,如果utils开发人员麻烦指定utils属性,然后那里列出的一切)。我建议您仅使用__all__进行快速编程,如果有的话。

这实际上是从命名空间的角度来看最接近import *的导入样式:execfileexecfile('utils.py')的作用大致相同,因为它转储from utils import *定义的所有符号毫不犹豫地进入你的工作区。一个微小的区别是,utils甚至不会将自己限制在execfile中的符号(如果已定义) - 实际上,__all__符号本身只会被丢弃在你的膝盖上以及其他一切。

除名称空间外,__all__from utils import *之间仍存在很多差异。一个是缓存:execfile('utils.py')上的第二次import呼叫将非常快(代码不会重新运行),但是对utils的第二次呼叫可能需要的时间与首先是因为代码重新运行。此外,execfile('utils.py')内部可能有一些代码(通常是测试代码),utils.py作者不希望在导入时运行,而当文件通过执行时utils。此类代码放在execfile子句中。