gpt4 book ai didi

python - 为什么从一个模块中导入一个函数比整个模块本身需要更长的时间?

转载 作者:IT老高 更新时间:2023-10-28 22:21:10 25 4
gpt4 key购买 nike

考虑:

>>> timeit.timeit('from win32com.client import Dispatch', number=100000)
0.18883283882571789
>>> timeit.timeit('import win32com.client', number=100000)
0.1275979248277963

仅导入 Dispatch 函数而不是整个模块需要更长的时间,这似乎违反直觉。有人可以解释为什么采用单个函数的开销如此糟糕吗?谢谢!

最佳答案

那是因为:

from win32com.client import Dispatch

相当于:

import win32com.client              #import the whole module first
Dispatch = win32com.client.Dispatch #assign the required attributes to global variables
del win32com #remove the reference to module object

但是 from win32com.client import Dispatch 有其自身的优势,例如,如果您在代码中多次使用 win32com.client.Dispatch 那么最好将其分配给一个变量,这样可以减少查找次数。否则每次调用 win32com.client.Dispatch() 将首先搜索 win32com 然后 clientwin32com ,最后是 win32com.client 中的 Dispatch


字节码比较:

从字节码可以看出,from os.path import splitext所需的步数比简单的import要多。

>>> def func1():
from os.path import splitext
...
>>> def func2():
import os.path
...
>>> import dis
>>> dis.dis(func1)
2 0 LOAD_CONST 1 (-1)
3 LOAD_CONST 2 (('splitext',))
6 IMPORT_NAME 0 (os.path)
9 IMPORT_FROM 1 (splitext)
12 STORE_FAST 0 (splitext)
15 POP_TOP
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
>>> dis.dis(func2)
2 0 LOAD_CONST 1 (-1)
3 LOAD_CONST 0 (None)
6 IMPORT_NAME 0 (os.path)
9 STORE_FAST 0 (os)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE

模块缓存:

请注意,在 from os.path import splitext 之后,您仍然可以使用 sys.modules 访问 os 模块,因为 python 会缓存导入的模块.

来自 docs :

Note For efficiency reasons, each module is only imported once per interpreter session. Therefore, if you change your modules, you must restart the interpreter – or, if it’s just one module you want to test interactively, use reload(), e.g. reload(modulename).

演示:

import sys
from os.path import splitext
try:
print os
except NameError:
print "os not found"
try:
print os.path
except NameError:
print "os.path is not found"

print sys.modules['os']

输出:

os not found
os.path is not found
<module 'os' from '/usr/lib/python2.7/os.pyc'>

时间比较:

$ python -m timeit -n 1 'from os.path import splitext'
1 loops, best of 3: 5.01 usec per loop
$ python -m timeit -n 1 'import os.path'
1 loops, best of 3: 4.05 usec per loop
$ python -m timeit -n 1 'from os import path'
1 loops, best of 3: 5.01 usec per loop
$ python -m timeit -n 1 'import os'
1 loops, best of 3: 2.86 usec per loop

关于python - 为什么从一个模块中导入一个函数比整个模块本身需要更长的时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17605659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com