Когда функция вызывается распаковкой аргументов, она, как представляется, увеличивает глубину рекурсии в два раза. Я хотел бы знать, почему это происходит.
Обычно:
depth = 0
def f():
global depth
depth += 1
f()
try:
f()
except RuntimeError:
print(depth)
#>>> 999
С распаковкой:
depth = 0
def f():
global depth
depth += 1
f(*())
try:
f()
except RuntimeError:
print(depth)
#>>> 500
В теории оба должны достичь около 1000:
import sys
sys.getrecursionlimit()
#>>> 1000
Это происходит на CPython 2.7 и CPython 3.3.
В PyPy 2.7 и PyPy 3.3 есть разница, но она намного меньше (1480 против 1395 и 1526 против 1395).
Как вы можете видеть из разборки, разница между ними невелика, кроме типа вызова (CALL_FUNCTION
vs CALL_FUNCTION_VAR
):
import dis
def f():
f()
dis.dis(f)
#>>> 34 0 LOAD_GLOBAL 0 (f)
#>>> 3 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
#>>> 6 POP_TOP
#>>> 7 LOAD_CONST 0 (None)
#>>> 10 RETURN_VALUE
def f():
f(*())
dis.dis(f)
#>>> 47 0 LOAD_GLOBAL 0 (f)
#>>> 3 BUILD_TUPLE 0
#>>> 6 CALL_FUNCTION_VAR 0 (0 positional, 0 keyword pair)
#>>> 9 POP_TOP
#>>> 10 LOAD_CONST 0 (None)
#>>> 13 RETURN_VALUE