Amir Saniyan
Amir Saniyan

Reputation: 13729

Odd behavior on printing function addresses in Python

I write the following code in Python:

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

print(fib, fib(10))

I think the correct output should be:

<function fib at 0x000001DF4BB13E18> 1 1 2 3 5 8

But The output is:

1 1 2 3 5 8 <function fib at 0x000001C60F823E18> None

The code prints None and its behavior is odd.

Why behavior of print function is odd?

Upvotes: 1

Views: 68

Answers (3)

MSeifert
MSeifert

Reputation: 152637

The behavior is correct. It's just that fib(10) is executed before you call print. That's because the arguments for the function call have to be executed before they are passed to the function.

So in fact you do calculate fib(10) (including all the prints inside the function) and then print fib and the result from the fib(10) call (which is None because your fib function contains no explicit return).

You can also invoke dis.dis to see the order of evaluation:

def f():
    print(fib, fib(10))

import dis

dis.dis(f)

Result:

 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

Upvotes: 3

Luke K
Luke K

Reputation: 895

Let's break this down.

First we'll look at the ordering:

print(fib, fib(10))

The call to fib will be evaluated first and pass its returned value into the print function.

fib(10) will do some printing of it's own and then exit. In this case it doesn't explicitly return a value and so gets treated as None

The above call to print can therefore be seen as

print(fib, None)

Which will result in printing the function address and then None

Upvotes: 1

kindall
kindall

Reputation: 184141

Both arguments to print() are fully evaluated before print() is actually called. Since the second argument to your main print() is fib(10), fib is called with argument 10 during this process. And since it prints things, these get printed during the evaluation process. The function itself doesn't contain a return statement, so it returns None, which is why that's printed.

Upvotes: 3

Related Questions