Ответ 1
Есть разница, потому что в версии import x
есть два поиска имен: один для имени модуля и второй для имени функции; с другой стороны, используя from x import y
, у вас есть только один поиск.
Вы можете увидеть это достаточно хорошо, используя этот модуль:
import random
def f_1():
random.seed()
dis.dis(f_1)
0 LOAD_GLOBAL 0 (random)
3 LOAD_ATTR 0 (seed)
6 CALL_FUNCTION 0
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
from random import seed
def f_2():
seed()
dis.dis(f_2)
0 LOAD_GLOBAL 0 (seed)
3 CALL_FUNCTION 0
6 POP_TOP
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
Как вы можете видеть, использование формы from x import y
выполняется немного быстрее.
С другой стороны, import x
дешевле, чем from x import y
, потому что там меньше меньше имен; посмотрим на дизассемблированный код:
def f_3():
import random
dis.dis(f_3)
0 LOAD_CONST 1 (-1)
3 LOAD_CONST 0 (None)
6 IMPORT_NAME 0 (random)
9 STORE_FAST 0 (random)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
def f_4():
from random import seed
dis.dis(f_4)
0 LOAD_CONST 1 (-1)
3 LOAD_CONST 2 (('seed',))
6 IMPORT_NAME 0 (random)
9 IMPORT_FROM 1 (seed)
12 STORE_FAST 0 (seed)
15 POP_TOP
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
Я не знаю причину, но форма from x import y
выглядит как вызов функции и, следовательно, даже дороже, чем ожидалось; по этой причине, если импортированная функция используется только один раз, это означает, что было бы быстрее использовать import x
, а если она используется более одного раза, она становится быстрее использовать from x import y
.
Это, как обычно, я предлагаю вам не следовать этим знаниям для вашего решения о том, как импортировать модули и функции, потому что это лишь некоторая преждевременная оптимизация. Лично я думаю, что во многих случаях явные пространства имен намного читабельнее, и я предлагаю вам сделать то же самое: использовать свое собственное чувство эстетики: -)