Fowler的Extract Variable重构方法(以前称为Introduce Explaining Variable)表示使用临时变量来使代码更清晰。这个想法是通过引入一个不需要的局部变量来阐明复杂的代码,并将该变量命名为出于展示目的。它还提倡对评论进行这种解释。Other languages优化临时变量,这样就没有时间或空间资源的成本。为什么Python不这样做?
In [3]: def multiple_of_six_fat(n): ...: multiple_of_two = n%2 == 0 ...: multiple_of_three = n%3 == 0 ...: return multiple_of_two and multiple_of_three ...: In [4]: def multiple_of_six_lean(n): ...: return n%2 == 0 and n%3 == 0 ...:
In [5]: import dis In [6]: dis.dis(multiple_of_six_fat) 2 0 LOAD_FAST 0 (n) 3 LOAD_CONST 1 (2) 6 BINARY_MODULO 7 LOAD_CONST 2 (0) 10 COMPARE_OP 2 (==) 13 STORE_FAST 1 (multiple_of_two) 3 16 LOAD_FAST 0 (n) 19 LOAD_CONST 3 (3) 22 BINARY_MODULO 23 LOAD_CONST 2 (0) 26 COMPARE_OP 2 (==) 29 STORE_FAST 2 (multiple_of_three) 4 32 LOAD_FAST 1 (multiple_of_two) 35 JUMP_IF_FALSE_OR_POP 41 38 LOAD_FAST 2 (multiple_of_three) >> 41 RETURN_VALUE In [7]: dis.dis(multiple_of_six_lean) 2 0 LOAD_FAST 0 (n) 3 LOAD_CONST 1 (2) 6 BINARY_MODULO 7 LOAD_CONST 2 (0) 10 COMPARE_OP 2 (==) 13 JUMP_IF_FALSE_OR_POP 29 16 LOAD_FAST 0 (n) 19 LOAD_CONST 3 (3) 22 BINARY_MODULO 23 LOAD_CONST 2 (0) 26 COMPARE_OP 2 (==) >> 29 RETURN_VALUE
答案 0 :(得分:10)
因为Python是一种高度动态的语言,引用可以影响行为。
比较以下内容,例如:
>>> id(object()) == id(object())
True
>>> ob1 = object()
>>> ob2 = object()
>>> id(ob1) == id(ob2)
False
如果Python“优化”ob1
和ob2
变量,行为就会发生变化。
Python对象的生命周期由引用计数控制。将weak references添加到混合加线程中,您将看到优化离开变量(甚至是本地变量)可能会导致不良行为更改。
此外,在Python中,从性能角度来看,删除这些变量几乎不会发生任何变化。本地命名空间已经过高度优化(值由数组中的索引查找);如果您担心解除引用局部变量的速度,那么您在项目的时间关键部分使用了错误的编程语言。
答案 1 :(得分:2)
Issue 2181(在函数末尾优化局部变量)有一些有趣的观点:
inspect
或sys._getframe()
。更改对象的生命周期。例如,以下示例中的myfunc
可能在优化后失败,因为目前Python保证在函数退出之前文件对象未关闭。 (糟糕的风格,但仍然)
def myfunc():
f = open('somewhere', 'r')
fd = f.fileno()
return os.fstat(fd)
不能改写为:
def bogus():
fd = open('somewhere', 'r').fileno()
# the file is auto-closed here and fd becomes invalid
return os.fstat(fd)
一位核心开发人员表示“它不太可能在实际代码中提供任何加速,我认为我们不应该为编译器增加复杂性。”