Why doesn't Python evaluate constant number arithmetic before compiling to bytecode? Why doesn't Python evaluate constant number arithmetic before compiling to bytecode? python python

Why doesn't Python evaluate constant number arithmetic before compiling to bytecode?


This is because x could have a __mul__ method with side-effects. x * 10 * 10 calls __mul__ twice, while x * 100 only calls it once:

>>> class Foo(object):...     def __init__ (self):...             self.val = 5...     def __mul__ (self, other):...             print "Called __mul__: %s" % (other)...             self.val = self.val * other...             return self... >>> a = Foo()>>> a * 10 * 10Called __mul__: 10Called __mul__: 10<__main__.Foo object at 0x1017c4990>

Automatically folding the constants and only calling __mul__ once could change behavior.

You can get the optimization you want by reordering the operation such that the constants are multiplied first (or, as mentioned in the comments, using parentheses to group them such that they are merely operated on together, regardless of position), thus making explicit your desire for the folding to happen:

>>> def f1(x):...     return 10 * 10 * x... >>> dis.dis(f1)  2           0 LOAD_CONST               2 (100)              3 LOAD_FAST                0 (x)              6 BINARY_MULTIPLY                   7 RETURN_VALUE 


Python evaluates expressions from left to right. For f2(), this means it will first evaluate x*10 and then multiply the result by 10. Try:

Try:

def f2(x):    10*10*x

This should be optimized.