Странное поведение при печати адресов функций в Python
Я пишу следующий код на Python:
def fib(n):
a, b = 0, 1
while b < n:
print(b, end=' ')
a, b = b, a + b
print(fib, fib(10))
Я думаю, что правильный вывод должен быть:
<function fib at 0x000001DF4BB13E18> 1 1 2 3 5 8
Но вывод:
1 1 2 3 5 8 <function fib at 0x000001C60F823E18> None
Код печатает None, и его поведение странно.
Почему поведение print
функция странная?
3 ответа
Поведение правильное. Это просто fib(10)
выполняется перед звонком print
, Это потому, что аргументы для вызова функции должны быть выполнены до того, как они будут переданы в функцию.
Так что на самом деле вы рассчитываете fib(10)
(включая все print
внутри функции), а затем распечатать fib
и результат от fib(10)
вызов (который None
потому что ваш fib
функция не содержит явных return
).
Вы также можете вызвать dis.dis
чтобы увидеть порядок оценки:
def f():
print(fib, fib(10))
import dis
dis.dis(f)
Результат:
10 0 LOAD_GLOBAL 0 (печать) 2 LOAD_GLOBAL 1 (fib) 4 LOAD_GLOBAL 1 (fib) 6 LOAD_CONST 1 (10) 8 CALL_FUNCTION 1 ----> вызов fib (10) 10 CALL_FUNCTION 2 ----> печать вызова ^------- количество аргументов! 12 POP_TOP 14 LOAD_CONST 0 (нет) 16 RETURN_VALUE
Оба аргумента print()
полностью оценены перед print()
на самом деле называется. Со вторым аргументом в ваш главный print()
является fib(10)
, fib
вызывается с аргументом 10
во время этого процесса. И поскольку он печатает вещи, они печатаются в процессе оценки. Сама функция не содержит return
заявление, так что оно возвращает None
Вот почему это напечатано.
Давайте разберемся с этим.
Сначала мы рассмотрим порядок:
print(fib, fib(10))
Вызов fib будет оценен первым и передаст возвращаемое значение в функцию print.
fib (10) выполнит собственную печать и затем выйдет. В этом случае он не возвращает явно значение и поэтому рассматривается как None
Таким образом, приведенный выше призыв к печати можно рассматривать как
print(fib, None)
Что приведет к печати адреса функции, а затем None