Итак, используя очень забавный модуль dis
, мы можем посмотреть фактический байт-код, сгенерированный из предоставленного вами кода Python. Для простоты я заменил func
и func2
на встроенные функции (int
и float
).
Итак, наш источник выглядит так:
def assign():
a = int()
b = float(a)
По сравнению с упрощенной версией:
def simple():
b = float(int())
И затем, начиная с интерпретатора cpython 2.7, мы можем увидеть байт-коды, сгенерированные из функции assign
:
dis.dis(assign)
2 0 LOAD_GLOBAL 0 (int)
3 CALL_FUNCTION 0
6 STORE_FAST 0 (a)
3 9 LOAD_GLOBAL 1 (float)
12 LOAD_FAST 0 (a)
15 CALL_FUNCTION 1
18 STORE_FAST 1 (b)
21 LOAD_CONST 0 (None)
24 RETURN_VALUE
Как вы можете видеть, оптимизация глазка не позволяет удалить ненужную промежуточную переменную, что приводит к дополнительным 2 инструкциям (STORE_FAST a
, LOAD_FAST a
) при сравнении с байт-кодами для упрощенного `простого метода:
dis.dis(simple)
2 0 LOAD_GLOBAL 0 (float)
3 LOAD_GLOBAL 1 (int)
6 CALL_FUNCTION 0
9 CALL_FUNCTION 1
12 STORE_FAST 0 (b)
15 LOAD_CONST 0 (None)
18 RETURN_VALUE
Это то же самое для интерпретатора CPython для Python 3.5 и для интерпретатора pypy для Python 2.7.