自己去发现吧!这dis https://docs.python.org/3/library/dis.html模块非常适合检查此类内容:
>>> 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
to 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 https://docs.python.org/3/library/inspect.htmling 函数对象:
>>> inspect.getargspec(db3)
ArgSpec(args=['x', '_ONE_THIRD'], varargs=None, keywords=None, defaults=(0.3333333333333333,))
您可以看到默认值缓存在其中。
EDIT:事实证明这更有趣——在 Python 3 中,它们确实被缓存了(在 Python 2.7 中,当您启用from __future__ import division
):
>>> 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
代替0.333..
另外,在2.7中直接使用整数除法withoutfuture-division 将缓存0
以及。
今天学到了新东西!