一起打印函数调用函数

时间:2018-07-20 23:48:18

标签: python python-3.x

我正在测试某些东西,我出于示例目的编写了这段代码。我觉得我得到的输出很奇怪。我希望函数调用一个接一个地执行,但是根据这个代码,两个打印语句都在执行之后执行彼此然后返回值一起打印。这意味着什么?在这种情况下,代码的流程是什么?

global num
num=5

def demo(num):
    num+=1
    print("hi")
    return(num)



print(demo(num),demo(num))

输出-

hi
hi
6 6

2 个答案:

答案 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)需要先执行ab的值。