我有一个文件utils.py
,其中包含一个名为f1()
的函数。
从另一个Python脚本中,我可以使用import utils
或execfile('utils.py')
并访问f1()
。这两种方法之间有什么区别?
我有一个文件utils.py
,其中包含一个名为f1()
的函数。
从另一个Python脚本中,我可以使用import utils
或execfile('utils.py')
并访问f1()
。这两种方法之间有什么区别?
有很多差异,但从您的角度来看,最重要的可能是 import
能够更好地控制 utils.py
中定义的对象所在的命名空间。
让我们考虑三种不同的 import
变体。首先是您提问的这种情况:
import utils
utils.f1()
utils
是唯一添加到您工作空间中的符号——任何预先存在于基础工作空间中的f1
都不会被覆盖,如果没有,则单独使用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 *
,如果必须使用的话。execfile
: execfile('utils.py')
做的事情与 from utils import *
几乎相同,因为它会将 utils
定义的所有符号不加思索地倾泻到你的工作区中。唯一的区别是,如果定义了 __all__
,execfile
甚至不会将自己限制于其中的符号,事实上, __all__
符号本身将与其他所有内容一起倾泻在你的膝盖上。from utils import *
和 execfile('utils.py')
之间仍然有很多区别。其中之一是缓存:对 utils
的第二个 import
调用将非常快(代码不会重新运行),但第二个调用 execfile('utils.py')
可能与第一个一样慢,因为代码将被重新运行。此外,可能存在一些代码(通常是测试代码)在 utils.py
中,作者并不希望在导入时运行,而是只有当文件通过 execfile
执行时才运行。这样的代码放在一个 if __name__ == '__main__':
子句中。
execfile
已死 -exec(open('utils.py').read())
长存,以及 IPython 的%run utils
。https://dev59.com/YHRC5IYBdhLWcg3wAcbU/ - jez