1

我在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函数的行为是奇怪的?

4

3 回答 3

3

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

于 2017-09-06T16:17:55.697 回答
3

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

所以实际上你确实计算fib(10)(包括print函数内的所有 s )然后打印fibfib(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 负载常数 1 (10)
              8 CALL_FUNCTION 1 ----> fib(10) 调用
             10 CALL_FUNCTION 2 ----> 打印调用
                                         ^------- 参数数量!
             12 POP_TOP
             14 LOAD_CONST 0(无)
             16 返回值
于 2017-09-06T16:18:14.753 回答
1

让我们分解一下。

首先我们来看一下排序:

print(fib, fib(10))

对 fib 的调用将首先被评估并将其返回值传递给 print 函数。

fib(10) 会自己打印一些内容,然后退出。在这种情况下,它没有显式返回值,因此被视为None

因此,上面的 print 调用可以被视为

print(fib, None)

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

于 2017-09-06T16:20:33.827 回答