假设我在Python中有一个使用常量计算浮点值的函数,如1/3。
def div_by_3(x):
return x * (1/3)
如果我重复调用该函数,是否会自动缓存1/3的值以提高效率?或者我是否必须手动执行以下操作?
def div_by_3(x, _ONE_THIRD=1/3):
return x * _ONE_THIRD
答案 0 :(得分:13)
了解自己! dis模块非常适合检查这类内容:
>>> from dis import dis
>>> def div_by_3(x):
... return x * (1/3.)
...
>>> dis(div_by_3)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 LOAD_CONST 2 (3.0)
9 BINARY_DIVIDE
10 BINARY_MULTIPLY
11 RETURN_VALUE
如您所见,1/3
计算每次都会发生。 (注意:我将3
更改为3.
以强制浮动除法,否则它只是0.您还可以启用future-division,它实际上改变了行为,请参阅下面的编辑部分) 。
你的第二种方法:
>>> def db3(x, _ONE_THIRD=1/3.):
... return x * _ONE_THIRD
...
>>> dis(db3)
2 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (_ONE_THIRD)
6 BINARY_MULTIPLY
7 RETURN_VALUE
有关第二个的更多信息可以通过inspect函数对象找到:
>>> inspect.getargspec(db3)
ArgSpec(args=['x', '_ONE_THIRD'], varargs=None, keywords=None, defaults=(0.3333333333333333,))
您可以看到默认值缓存在那里。
编辑:事实证明这更有趣 - 在Python 3中它们会被缓存(当你启用from __future__ import division
时也会在Python 2.7中):
>>> dis.dis(div_by_3)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 3 (0.3333333333333333)
6 BINARY_MULTIPLY
7 RETURN_VALUE
在Python 3或2.7-with-future-division中切换到整数除法(//
)并不会改变这一点,它只是将常量改为0
而不是{ {1}}此外,直接在2.7 中使用整数除法而不使用 future-division也会缓存0.333..
。
今天学到了新东西!