Skip to content Skip to sidebar Skip to footer

How Is A Python Function's Name Reference Found Inside It's Declaration?

It's totally unexpected (to me at least) that foo would know foo inside of the function def for foo. What the heck is going on here? >>> def foo(x): ... print 'wow' ...

Solution 1:

Nothing really mysterious.

There is, I believe a two pass aspect to this and you are doing a late evaluation in the body of the function.

update: I qualified my explanation of what happens after the definition step - it looks as some things do happen with the function code before it gets called. Wally's answer is better than mine in that respect.

Pass #1 - def foo(x) is found and set on the module's namespace. Probably adds the function parameters as well.

That's all, you don't drill down in the code.

update: Actually, I am not so sure about the code not being processed in some way before the call. Looking at foo.func_code internals showed no great difference on before and after call.

Also, if you have a syntax error like parenthesis nesting or whitespace problems that does show up before even calling the function so something's picking that up ahead of the call. See my code at the end.

I'll guess that the code is parsed but any variable resolution gets deferred until actual execution.

Pass #2 - you call foo(x), it is found and called.

The function's code gets executed for the first time.

When you hit globals()["foo"], it picks up the existing reference stored in #1.

You can also see some hints of this behavior when you run coverage.py or similar. On import, all the outer definitions in a module are flagged as covered.

But the actual code only gets covered when you call it.

Another way to think of it is that you need that namespacing pass first to set up references, before proceeding further. Otherwise, in my code below, foo would not find bar.

Here's some code I played to distinguish execution error vs syntax error...

deffoo(x):
    """comment/uncomment to see behavior"""pass# return bar(x)   #this worksreturn bar2(x)  #call time error#   return bar(x) bad whitespace  #IndentationError, nothing runsprint"foo defined"defbar(x):
    return x*2print"calling foo#1"try:
    print foo(3)
except Exception, e:
    print e

#let's make it so there is a bar2...
bar2 = bar

print"calling foo#2"try:
    print foo(6)
except Exception, e:
    print e

Post a Comment for "How Is A Python Function's Name Reference Found Inside It's Declaration?"