Are persistent computing cached in Python?

Say I have a function in Python that uses a constant computed float value, such as 1/3.

def div_by_3(x): return x * (1/3) 

If I call the function again, will the 1/3 value be automatically cached for efficiency? Or I need to do something manually, like the following:

 def div_by_3(x, _ONE_THIRD=1/3): return x * _ONE_THIRD 
+13
python
Oct 07 '15 at 19:09
source share
1 answer

Find out for yourself! The dis module is great for checking these kinds of things:

 >>> 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 

As you can see, 1/3 calculation happens every time. (Note: I changed 3 to 3. to force float division, otherwise it will be only 0. You can also include future division, which actually changed the behavior, see the Editing section below).

And your second approach:

 >>> 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 

More information on the second can be found on the inspect function object:

 >>> inspect.getargspec(db3) ArgSpec(args=['x', '_ONE_THIRD'], varargs=None, keywords=None, defaults=(0.3333333333333333,)) 

You can see that the default value is cached there.

EDIT . Turns out it's a little more interesting. In Python 3, they get caching (and also in Python 2.7 when you enable 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 

Switching to integer division ( // ) in Python 3 or 2.7-with-future-division does not change this, it just changes the constant as 0 instead of 0.333.. Also, using integer division directly in 2.7 without future division will cache 0 .

Learned something new today!

+12
07 Oct '15 at 19:13
source share



All Articles