5

My apologies for what some may regard as a fundamental question. In the following simple code:

def greet(name):
    def say_hi():
        print('Preparing to greet...')
        print('Hi', name, '!')       
        print('Greeting given.')
    return say_hi

What is the sequence of events when 'greet' is called with a formal parameter and the interpreter encounters the 'say_hi' function. I see that a reference to it is returned (forming a closure I assume?), but is the inner function executed or simply 'read' and not called until the programmer writes code like the following:

f = greet('Caroline')
f()
6
  • 1
    Did you try it to find out? Commented Dec 24, 2015 at 19:55
  • Yes, I did. The code produces the expected output but the sequence of events within the outer function are not entirely clear. It looks as though the inner function is 'read', but not executed until a call is made to the reference returned. Commented Dec 24, 2015 at 19:57
  • 2
    How is that not clear, though? It's obvious that it doesn't get executed, because nothing is printed. So what is confusing you about that? Commented Dec 24, 2015 at 20:00
  • I was looking at decorators and the explanation the author gave was rather convoluted in that he stated that the inner function was executed when the outer function was parsed. I didn't think that was correct, but I was not sure if I misinterpreted (no pun intended) a more subtle aspect of closures and decorators. I'm enlightened now :) Commented Dec 24, 2015 at 20:12
  • adding the quote from the author may make the question more clear and help others find it. Commented Dec 24, 2015 at 20:15

1 Answer 1

7

Since every thing in python is about runtime (except compile time tasks like peephole optimizer and etc.), python doesn't call your function unless you call it.

You can see this behavior by using dis function from dis module, which returns the relative bytecode of your function :

>>> def greet(name):
...     def say_hi():
...         print('Preparing to greet...')
...         print('Hi', name, '!')       
...         print('Greeting given.')
...     return say_hi
... 
>>> import dis
>>> 
>>> dis.dis(greet)
  2           0 LOAD_CLOSURE             0 (name)
              3 BUILD_TUPLE              1
              6 LOAD_CONST               1 (<code object say_hi at 0x7fdacc12c8b0, file "<stdin>", line 2>)
              9 MAKE_CLOSURE             0
             12 STORE_FAST               1 (say_hi)

  6          15 LOAD_FAST                1 (say_hi)
             18 RETURN_VALUE  

As you can see in part 6 python just load the function as a code object in a CONST value.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.