Ответ 1
Это связано с тем, что x
может иметь метод __mul__
с побочными эффектами. x * 10 * 10
дважды вызывает __mul__
, а x * 100
вызывает его только один раз:
>>> 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 * 10
Called __mul__: 10
Called __mul__: 10
<__main__.Foo object at 0x1017c4990>
Автоматическое сложение констант и только вызов __mul__
один раз могут изменить поведение.
Вы можете получить нужную оптимизацию, переупорядочив операцию таким образом, чтобы константы сначала умножались (или, как указано в комментариях, с помощью круглых скобок, чтобы группировать их так, чтобы они просто работали вместе, независимо от положения), таким образом делая явное ваше стремление к свертыванию:
>>> 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