Ответ 1
Это потому, что:
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
, а затем client
внутри win32com
и, наконец, Dispatch
внутри win32com.client
.
Сравнение байтового кода:
Из байтового кода видно, что количество шагов, необходимых для 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
вы все равно можете получить доступ к модулю os
, используя sys.modules
, потому что python кэширует импортированные модули.
От docs:
Примечание. По соображениям эффективности каждый модуль импортируется только один раз за интерпретатор. Поэтому, если вы меняете свои модули, вы должны перезапустите интерпретатор - или, если его только один модуль, который вы хотите протестировать интерактивно использовать
reload()
, например.reload(modulename)
.
Demo:
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