Я проверил .__code__
объектов для двух функций, которые я считал разными, но обнаружил, что они идентичны, для множества выражений. Если объекты кода идентичны, насколько я понимаю, они компилируются в один и тот же байт-код и, таким образом, являются «одинаковыми» функциями.
Таблица ниже содержит элементы, вставленные перед ; pass
, что делает g
разными __code__
. Поскольку f
является функцией «ничего не делать», это предполагает, что все, что находится под «одинаковым», до никогда не выполняет , включая длинную арифметику c. Кроме того, кортеж является «одинаковым», но список и строка являются «diff», поэтому мы можем заключить, что неназначенные выражения, содержащие неизменяемые литералы , не оцениваются. Но есть еще 1/0
, которое может быть «исключением» из-за возникновения исключения - тогда что с 10**99
против 10**9
? 10**99
не вызывает исключения и может быть назначен.
Я не мог сказать многого из профилирования; и «same», и «diff» имели неразличимое время выполнения. Когда они могли быть , однако, это всегда было с «diff».
Если «same» никогда не выполняются, то как Python определяет, что выполнять, а что нет? Если они выполняются, как выглядят их объекты кода?
То же :
0
, (0,)
, True
, False
, None
10 ** 9
()
-314159.265358 ** (1/12345) / 2.718281828 + 500 - 7j
Diff :
[0]
, {0: 0}
10 ** 99
[]
, {}
, ""
Код сравнения :
def compare(fn1, fn2):
for name in dir(fn1.__code__):
if (name.startswith("co_") and
name not in ("co_filename", "co_name", "co_firstlineno")):
v1 = getattr(fn1.__code__, name)
v2 = getattr(fn2.__code__, name)
if v1 == v2:
print(name.ljust(18), "same")
else:
print(name.ljust(18), "diff", v1, v2)
def f():
pass
def g():
10 ** 99; pass
Различаются следующие значения: co_name
(всегда), co_filename
(I Python), co_firstlineno
(из файла ) - но не влияет на то, что "выполняется", поправьте меня, если нет; от docs , co_code
- вот что должно отличаться.
Примечание : принятый ответ пропускает важную часть интуиции: код неназначенных литералов может быть сохранен, если код, требуемый для хранения значения занимает больше памяти, чем код, необходимый для хранения выражения для вычисления значения ; так обстоит дело с 10 ** 99
(по крайней мере, так утверждалось в комментариях). См. Комментарии под ответом для получения дополнительной информации.