开发者

how does the compile() work in python?

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(a开发者_运维技巧bc == 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!


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜