1

I have two code which really confused me.

def get_context():
    __gc = globals()
    __lc = locals()

    def precompiler(code):
        exec code in __lc

    def compiler(script, scope):
        return compile(script, scope, 'eval')

    def executor(expr):
        return eval(expr, __gc, __lc)

    return precompiler, compiler, executor

maker1, compiler1, executor1 = get_context()
maker2, compiler2, executor2 = get_context()

maker1("abc = 123")
maker2("abc = 345")
expr1 = compiler1("abc == 123", "test.py")
print "executor1(abc == 123):", executor1(expr1)
print "executor2(abc == 123):", executor2(expr1)

the result is:
executor1(abc == 123): True
executor2(abc == 123): False

Why the compile execute in the closure only once and the byte-code could run in both?

And there is another code here:

def get_context():
    __gc = globals()
    __lc = locals()

    test_var = 123

    def compiler(script, scope):
        return compile(script, scope, 'eval')

    def executor(expr):
        return eval(expr, __gc, __lc)

    return compiler, executor


compiler1, executor1 = get_context()
compiler2, executor2 = get_context()

expr1 = compiler1("test_var == 123", "test.py")
print "executor1(test_var == 123):", executor1(expr1)
print "executor2(test_var == 123):", executor2(expr1)

the result is:
NameError: name 'test_var' is not defined

And how did this happen?

Why does the compile need to check the environment(variable or some others) of the closure while it is not dependent on the closure? This is what I confused!

2
  • "Why the compile execute in the closure only once and the byte-code could run in both?" its not entirely clear what you are asking here. Perhaps you could explain what you expected to happen? Commented Sep 27, 2011 at 4:30
  • Why does the compile need to check the environment(variable or some others) of the closure while it is not dependent on the closure? This is what I confused! Commented Sep 27, 2011 at 4:45

2 Answers 2

1

In your first example, you are executing 'abc=123' in your first context, and 'abc=345' in your second context. So 'test_var==123' is true in your first context and false in your second context.

In your second example, you have caught an interesting situation where the interpreter has removed test_var from the context because test_var isn't referenced.

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

3 Comments

oh, I see. But I still confused what does the compile() exactly do?
why compile need the context, but byte-code could execute in another context?
The second parameter to compile is just a string indicating where the code came from, it has nothing to do with the variable values.
1

For your first question, compile just takes the python code and produces the bytecode. It it is not dependent in any way on the closure where you compiled it. Its not different then if you had produced say, a string. That string isn't permantely tied to the function where it was created and neither is the code object.

For your second question, locals() builds a dictionary of the local variables when it is called. Since you setup test_var after calling locals it doesn't have it. If you want test_var inside locals, you need to call it afterwards.

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.