Python中的好习惯还是坏习惯:在文件中间导入
假设我有一个比较长的模块,但只需要用到一个外部模块或方法一次。
在模块的中间导入这个方法或模块可以吗?
还是说,import
语句应该只放在模块的开头部分。
举个例子:
import string, pythis, pythat
...
...
...
...
def func():
blah
blah
blah
from pysomething import foo
foo()
etc
etc
etc
...
...
...
请解释一下你的答案,并附上相关的PEP或其他相关资料的链接
9 个回答
大家都提到了PEP(Python增强提案),但还要注意不要在关键代码中间放置导入语句。至少在Python 2.6版本中,如果一个函数里有导入语句,会需要更多的字节码指令。
>>> def f():
from time import time
print time()
>>> dis.dis(f)
2 0 LOAD_CONST 1 (-1)
3 LOAD_CONST 2 (('time',))
6 IMPORT_NAME 0 (time)
9 IMPORT_FROM 0 (time)
12 STORE_FAST 0 (time)
15 POP_TOP
3 16 LOAD_FAST 0 (time)
19 CALL_FUNCTION 0
22 PRINT_ITEM
23 PRINT_NEWLINE
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
>>> def g():
print time()
>>> dis.dis(g)
2 0 LOAD_GLOBAL 0 (time)
3 CALL_FUNCTION 0
6 PRINT_ITEM
7 PRINT_NEWLINE
8 LOAD_CONST 0 (None)
11 RETURN_VALUE
在2001年,Python的邮件列表上对此话题进行了详细讨论:
https://mail.python.org/pipermail/python-list/2001-July/071567.html
以下是讨论中提到的一些理由。来自Peter Hansen的观点,他列出了三个不把所有导入放在文件顶部的理由:
在函数中导入的可能原因:
可读性:如果某个导入只在一个函数中需要,而且这个需求很可能不会改变,那么把它放在那个函数里会更清晰、更整洁。
启动时间:如果你不把导入放在函数定义外面,那么当你的模块被其他模块首次导入时,这些导入不会执行,而是等到某个函数被调用时才会执行。这样可以延迟导入的开销(如果这些函数可能根本不会被调用,甚至可以避免导入)。
总会有比我们想到的更多的理由。
Just van Rossum也补充了一个第四个理由:
- 开销:如果一个模块导入了很多其他模块,而实际上只有少数几个会被用到。这和“启动时间”的理由类似,但更进一步。如果一个使用你模块的脚本只用到一小部分功能,这样可以节省不少时间,尤其是当那些可以避免的导入还导入了很多模块时。
还有一个第五个理由是,局部导入可以避免循环导入的问题。
欢迎你去阅读那个讨论串,了解更全面的内容。
PEP 8 的作者明确指出:
导入的内容总是放在文件的最上面,紧接着模块的注释和文档字符串之后,然后再是模块的全局变量和常量。
PEP 8 应该成为任何“内部”风格指南的基础,因为它总结了核心 Python 团队认为最有效的编程风格(当然,个别意见会有所不同,就像其他语言一样,但大家达成共识的 BDFL 也同意 PEP 8)。