我正在测试某些东西,我出于示例目的编写了这段代码。我觉得我得到的输出很奇怪。我希望函数调用一个接一个地执行,但是根据这个代码,两个打印语句都在执行之后执行彼此然后返回值一起打印。这意味着什么?在这种情况下,代码的流程是什么?
global num
num=5
def demo(num):
num+=1
print("hi")
return(num)
print(demo(num),demo(num))
输出-
hi
hi
6 6
答案 0 :(得分:2)
我希望函数调用一个接一个地执行
这就是事实。
但是print
不可能在demo
调用之前发生,因为它试图打印出这些调用返回的值。 (您可以粗略地认为这是在任何出现括号的地方的特殊情况:2 * (3+4)
不能乘以2
,直到将其加上3+4
,而print(demo(num), demo(num))
不能打印demo(num)
和demo(num)
的结果,直到它们被调用为止。但是不要从字面上理解 。
因此,这些demo
呼叫从左到右发生,然后print
呼叫发生。
更详细地,让我们逐步了解它如何评估这一行:
print(demo(num),demo(num))
…Python必须这样做:
print
查找为内置名称来求值,该名称会找到内置的print
函数。demo
查找为一个全局名称来求值,该名称会找到您定义的全局demo
函数。num
查找为一个全局名称来进行评估,该名称会找到全局5
的值。num
获取传入的值5
。num += 1
将局部变量(参数是局部变量)num
更新为6
。print("hi")
打印出hi
。return(num)
返回局部变量6
的值。hi
并返回6
。print
返回的函数,以便打印出6 6
。如果需要严格的定义,请参见参考文档中的Calls。特别是(去除无关位)
call ::= primary "(" [argument_list] ")"
...
主要对象必须评估为可调用对象……。在尝试调用之前,将评估所有参数表达式。
根据此代码,两个打印语句都彼此执行,然后将返回值一起打印
是的。必须依次执行两个函数调用,以便它可以将值传递给print
函数。执行它们会打印两次Hi
。然后,它具有所有值,因此可以print
使用它们,由于两个值都是6 6
,因此将打印出6
。
答案 1 :(得分:2)
程序评估与算术一样具有操作顺序。同样,它也不总是很直观,尤其是当我们在阅读时从左到右,从上到下“消耗”东西时。
那么,有什么用呢? 让我们成为python解释器,看看为什么操作顺序很重要。
# A wild statement appears. Time to compute!
print(demo(num),demo(num))
# I cant't print yet! i'm missing info!
我需要先评估此demo(num)
,默认情况下,我要在远离全局变量的封闭空间内进行评估
# evaluating demo(num=5) - num here is a new local variable, it has no relation to the global one defined above
num+=1 # num = 6
print("hi") # [[[PRINT hi]]] ~> to console
return 6 # returns the value 6 filling in another piece of the puzzle
我们现在在哪里?几乎准备好调用此打印文件,只需再次执行此演示操作
print(6, demo(num))
# What is num though?
# Well, the only num I know of out here in global space is 5
print(6, demo(5))
# evaluate: demo(5)
这似乎很熟悉!
# evaluating: demo(num=5) - again, a NEW local variable is created just for this function call
num+=1 # num = 6
print("hi") # [[[PRINT hi]]] ~> to console
return 6
最后,print具有其所需的所有参数
print(6, 6) # [[[PRINT 6 6]]] ~> to console
print
不是魔术,它只是另一个功能!与您编写的demo
相同。
在提供所有参数之前,函数不会求值。
print(a, b)
需要先执行a
和b
的值。