您好 Jet Blue 以便更好地理解 python wiki PerformanceTips
import 语句几乎可以在任何地方执行。将它们放在函数中以限制它们的可见性和/或减少初始启动时间通常很有用。尽管 Python 的解释器被优化为不会多次导入同一个模块,但在某些情况下重复执行 import 语句会严重影响性能。
考虑以下两个 sn-ps 代码(我相信最初来自 Greg McFarlane - 我发现它在 comp.lang.python python-list@python.org 帖子中没有归属,后来在另一个来源中归属于他):
def doit1():
import string ###### import statement inside function
string.lower('Python')
for num in range(100000):
doit1()
或:
import string ###### import statement outside function
def doit2():
string.lower('Python')
for num in range(100000):
doit2()
doit2 将比 doit1 运行得快得多,即使对字符串模块的引用在 doit2 中是全局的。这是一个使用 Python 2.3 和新的 timeit 模块运行的 Python 解释器会话,它显示了第二个比第一个快多少:
def doit1():
import string
string.lower('Python')
import string
def doit2():
string.lower('Python')
import timeit
t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()')
t.timeit()
11.479144930839539
t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()')
t.timeit()
4.6661689281463623
字符串方法在 Python 2.0 中被引入该语言。这些提供了一个完全避免导入并运行得更快的版本:
def doit3():
'Python'.lower()
for num in range(100000):
doit3()
这是来自 timeit 的证明:
def doit3():
'Python'.lower()
t = timeit.Timer(setup='from main import doit3', stmt='doit3()')
t.timeit()
2.5606080293655396
上面的例子显然有点做作,但总的原则是成立的。
请注意,将导入放入函数中可以加快模块的初始加载速度,尤其是在可能不需要导入的模块时。这通常是一种“惰性”优化的情况——避免工作(导入模块,这可能非常昂贵),直到您确定需要它。
这只是在模块根本没有被导入(从任何模块)的情况下显着节省 - 如果模块已经加载(对于许多标准模块,如 string 或 re ),避免导入不会为您节省任何东西。要查看系统中加载了哪些模块,请查看 sys.modules。
惰性导入的一个好方法是:
email = None
def parse_email():
global email
if email is None:
import email
这样,电子邮件模块只会在第一次调用 parse_email() 时被导入一次。