Странное поведение при печати адресов функций в 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

Другие вопросы по тегам