2

Reading the answer to the question, What's the difference between globals(), locals(), and vars()?, The following explanation was given for how locals() works:

if locals() is called inside a function it constructs a dictionary of the function namespace as of that moment and returns it -- any further name assignments are not reflected in the returned dictionary, and any assignments to the dictionary are not reflected in the actual local namespace

In a comment, it was mentioned that

The part "and any assignments to the dictionary are not reflected in the actual local namespace" might be worded a bit to definite.

linking to the following code:

def f():
    exec "pass"
    locals()["x"] = 42
    print(x)
f()

This returns 42 (at least in CPython 2.7). Without the line exec "pass" python throws a NameError because it can't find 'x'. This fits with the definition that changes to the dictionary returned by locals() inside a function are not reflected in the namespace. Why does adding the line exec "pass" allow these changes to be reflected? Is this somehow tricking python into thinking it has excited the function?

Community
  • 1
  • 1
Wilduck
  • 13,822
  • 10
  • 58
  • 90
  • 3
    Don't rely on it because such thing was removed from Python 3. – JBernardo Nov 01 '11 at 22:31
  • I should be clear. I have no intention of using this. I'm just fascinated that it works, and was wondering what implementation detail is behind it. – Wilduck Nov 01 '11 at 22:32

1 Answers1

3

This answer to another question has a nice explanation of what is going on. Here is the summary:

The presence of an exec statement causes Python 2 to compile f in a totally non-optimized fashion, so locals are in a dict instead of in an array as they normally would be. (The performance hit can be considerable).

Community
  • 1
  • 1
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
  • It's funny. When I wrote this question I thought to myself "I wish Alex Martelli was still answering questions here, he'd be all over this." Turns out, I was right. Thanks. – Wilduck Nov 02 '11 at 15:45