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

Python中打印函数地址的奇怪行为,python,function,printing,function-address,Python,Function,Printing,Function Address,我用Python编写以下代码: def fib(n): a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a + b print(fib, fib(10)) def fib(n): a、 b=0,1 而b the fib(10) call 10 CALL_FUNCTION 2 ----> the print ca

我用Python编写以下代码:

def fib(n):
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a + b

print(fib, fib(10))
def fib(n):
a、 b=0,1
而b
我认为正确的输出应该是:

<function fib at 0x000001DF4BB13E18> 1 1 2 3 5 8
112358
但结果是:

1 1 2 3 5 8 <function fib at 0x000001C60F823E18> None
1 1 2 3 5 8无
代码打印None,其行为很奇怪


为什么
print
函数的行为是奇怪的?

在实际调用
print()
之前,对
print()
的两个参数都进行了完整的评估。由于main
print()
的第二个参数是
fib(10)
fib
在这个过程中与参数
10
一起调用。因为它会打印东西,所以在评估过程中会打印出来。函数本身不包含
return
语句,因此它返回
None
,这就是为什么要打印它。

在实际调用
print()
之前,对
print()
的两个参数都进行了完全求值。由于main
print()
的第二个参数是
fib(10)
fib
在这个过程中与参数
10
一起调用。因为它会打印东西,所以在评估过程中会打印出来。函数本身不包含
return
语句,因此它返回
None
,这就是为什么要打印它。

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

因此,实际上您确实计算了
fib(10)
(包括函数中的所有
print
),然后打印
fib
,以及
fib(10)
调用的结果(这是
None
,因为
fib
函数不包含显式的
返回值)

您还可以调用
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 10 0加载\u全局0(打印) 2负载_全局1(fib) 4负载_全局1(fib) 6负载常数1(10) 8调用函数1-->fib(10)调用 10调用\u函数2-->打印调用 ^-------争论的数量! 12件流行上衣 14负载常数0(无) 16返回值
这种行为是正确的。只是在调用
print
之前执行了
fib(10)
。这是因为函数调用的参数必须在传递给函数之前执行

因此,实际上您确实计算了
fib(10)
(包括函数中的所有
print
),然后打印
fib
,以及
fib(10)
调用的结果(这是
None
,因为
fib
函数不包含显式的
返回值)

您还可以调用
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 10 0加载\u全局0(打印) 2负载_全局1(fib) 4负载_全局1(fib) 6负载常数1(10) 8调用函数1-->fib(10)调用 10调用\u函数2-->打印调用 ^-------争论的数量! 12件流行上衣 14负载常数0(无) 16返回值
让我们来分析一下

首先,我们将了解订购情况:

print(fib, fib(10))
首先计算对fib的调用,并将其返回值传递给print函数

fib(10)将自己进行一些打印,然后退出。在这种情况下,它不显式返回值,因此被视为
None

因此,上述打印调用可以被视为

print(fib, None)

这将导致打印函数地址,然后将其分解为
None

首先,我们将了解订购情况:

print(fib, fib(10))
首先计算对fib的调用,并将其返回值传递给print函数

fib(10)将自己进行一些打印,然后退出。在这种情况下,它不显式返回值,因此被视为
None

因此,上述打印调用可以被视为

print(fib, None)

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

“括号中的值总是先执行”是误导性的,考虑到在
f()+(g()+h())
等情况下,
f()
g()
h()
之前进行求值。非常适合
dis
“括号中的值总是先执行”是有误导性的,因为在像
f()+(g()+h())
这样的情况下,
f()
g()
h()
之前进行求值。
dis
函数的良好使用总是先求值“不是真的,措词不当。在包含它们的函数之前求值。Will edit“始终首先计算函数”不正确。措辞不当。在包含它们的函数之前求值。将编辑