Python 中打印函数地址的奇怪行为

Odd behavior on printing function addresses in 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 函数的行为很奇怪?

print() 的两个参数在实际调用 print() 之前都已完成评估。由于 main print() 的第二个参数是 fib(10),因此在此过程中使用参数 10 调用 fib。由于它会打印东西,因此这些东西会在评估过程中打印出来。该函数本身不包含 return 语句,因此它 returns None,这就是打印的原因。

行为正确。只是在你调用print之前执行了fib(10)。那是因为函数调用的参数必须在传递给函数之前执行。

所以实际上你确实计算了 fib(10)(包括函数内的所有 print),然后打印 fibfib(10) 调用的结果(这是 None 因为你的 fib 函数不包含明确的 return).

您还可以调用 dis.dis 来查看计算顺序:

def f():
    print(fib, fib(10))

import dis

dis.dis(f)

结果:

 10           0 LOAD_GLOBAL              0 (print)
              2 LOAD_GLOBAL              1 (fib)
              4 LOAD_GLOBAL              1 (fib)
              6 LOAD_CONST               1 (10)
              8 CALL_FUNCTION            1             ----> the fib(10) call
             10 CALL_FUNCTION            2             ----> the print call
                                         ^-------  number of arguments!
             12 POP_TOP
             14 LOAD_CONST               0 (None)
             16 RETURN_VALUE

我们来分解一下。

首先我们来看看顺序:

print(fib, fib(10))

将首先评估对 fib 的调用,并将其 returned 值传递给打印函数。

fib(10) 会自己打印一些然后退出。在这种情况下,它没有明确 return 一个值,因此被视为 None

因此,上面的打印调用可以看作

print(fib, None)

这将导致打印函数地址,然后 None