为什么python在定义期间尝试计算p
的值?定义此功能需要很长时间。
def f():
raise Exception('Some error')
p = 2322111239**42322222334923492304923
print 'Defined!'
如果在定义期间计算p
的值,为什么可以定义此函数而不会出错?
def f():
return 4
p = 11/0
这个显然工作正常,因为不涉及常量:
def f():
raise Exception('Some error')
x=42322222334923492304923
p = 2322111239**x
print 'Defined!'
答案 0 :(得分:8)
这是窥视孔优化器:
http://hg.python.org/cpython/file/eabff2a97b5b/Python/peephole.c#l88
特别参见第104-106行
case BINARY_POWER:
newconst = PyNumber_Power(v, w, Py_None);
break;
目的是以更慢的定义(读取:导入)时间为代价加速函数的运行时执行。这是有道理的,因为你只需要编译一次该函数的代码,但你可能需要多次调用它。
我相信优化器是由Raymond Hettinger编写的,他在SO上非常活跃,也许他可以确认我的主张。
答案 1 :(得分:7)
解释器的这个功能称为constant folding
(有关一些不错的信息,请参阅here)。存在若干问题,即使是过于激进的恒定折叠。类似的问题也可以用于内存,其中大量内存被分配并再次直接丢弃(参见here)。
答案 2 :(得分:3)
让我们尝试一个更合理的数字:
>>> def f():
... p=123**45
...
如果使用dis查看字节代码,可以看到在调用函数之前正在定义p的值:
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 3 (11110408185131956285910790587176451918559153212268021823629073199866111001242743283966127048043)
3 STORE_FAST 0 (p)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE