Reputation: 2365
I was testing with something and I wrote this code for example purposes.I felt the output I got was weird.I expected that function calls are executed one after the other but according to this code both the print statements are getting executed after each other and then the return values are printed together.What does this mean and what is the flow of the code in this case?
global num
num=5
def demo(num):
num+=1
print("hi")
return(num)
print(demo(num),demo(num))
output-
hi
hi
6 6
Upvotes: 1
Views: 2073
Reputation: 1046
Program evaluation has an order of operations just like arithmetic does. And similarly, it's not always intuitive, especially when we "consume" things left to right, up to down while reading.
So, what gives? Lets become the python interpreter and see why order of operations is important.
# A wild statement appears. Time to compute!
print(demo(num),demo(num))
# I cant't print yet! i'm missing info!
I need to evaluate this first demo(num)
, and by default im going to do it a closed room away from globals
# 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
Where are we at now? Almost ready to call this print, just need to do this demo thing again
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)
This seems familiar!
# 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
Finally, print has all its arguments it needs
print(6, 6) # [[[PRINT 6 6]]] ~> to console
print
is not magic, it's just another function! Same as the demo
you wrote.
And functions will not evaluate until all their parameters are supplied.
print(a, b)
needs the values of a
& b
before it can do its thing.
Upvotes: 3
Reputation: 366103
I expected that function calls are executed one after the other
That's exactly what happens.
But there's no way the print
can happen before the demo
calls, because it's trying to print out the values returned by those calls. (You can loosely think of this as a special case of anywhere you see parentheses: 2 * (3+4)
can't multiply by 2
until it's added 3+4
, and print(demo(num), demo(num))
can't print the results of demo(num)
and demo(num)
until it's called them. But don't take that too literally.)
So, those demo
calls happen left to right, then the print
call happens.
In more detail, let's step through how it evaluates this line:
print(demo(num),demo(num))
… Python has to do this:
print
by looking it up as a builtin name, which finds the builtin print
function.demo
by looking it up as a global name, which finds the global demo
function that you defined.num
by looking it up as a global name, which finds the global 5
value.num
gets the value passed in, 5
.num += 1
updates the local variable (parameters are local variables) num
to 6
.print("hi")
prints out hi
.return(num)
returns the value of the local variable, 6
.hi
and returns 6
.print
on the two arguments returned by the two calls, so it prints out 6 6
.If you want the rigorous definition, he details are covered in Calls in the reference documentation. In particular (stripping out irrelevant bits)
call ::= primary "(" [argument_list] ")"
…
The primary must evaluate to a callable object…. All argument expressions are evaluated before the call is attempted.
according to this code both the print statements are getting executed after each other and then the return values are printed together
Yes. The two function calls have to be executed in order, so that it can get the values to pass to the print
function. Executing them prints out Hi
twice. Then it has all the values, so it can print
them, which prints out 6 6
, since both values are 6
.
Upvotes: 2