为什么在编组代码上调用exec的函数会给出关于全局变量的错误? [英] Why does my function that calls exec on marshalled code give an error about globals?

查看:106
本文介绍了为什么在编组代码上调用exec的函数会给出关于全局变量的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在玩 compile() 元帅模块

当我像这样使用exec运行此脚本时

When I run this script using exec like this

with open('simple.py', 'r') as f:
    code = f.read()
exec code

它给出了预期的输出.

This is a simple script that should count to 3.
This is iteration number 1
This is iteration number 2
This is iteration number 3
Inside foo()...

但是,如果我像这样介绍compile()marshal.dump()marshal.load()

However, when if I introduce compile(), marshal.dump(), and marshal.load() like this

import marshal

def runme(file):
    with open(file, "r") as f:
        code = marshal.load(f)
    exec code

with open("simple.py", "r") as f:
    contents = f.read()

code = compile(contents, "simple.py", "exec")
with open("marshalled", "w") as f:  
    marshal.dump(code, f)

runme("marshalled")

它会打印出预期输出的开头,然后输出错误信息

it prints the beginning of the expected output and then errors out

This is a simple script that should count to 3.
This is iteration number 1
This is iteration number 2
This is iteration number 3
Traceback (most recent call last):
  File "./exec_within_function.py", line 17, in <module>
    runme("marshalled")
  File "./exec_within_function.py", line 8, in runme
    exec code
  File "simple.py", line 15, in <module>
    main()
  File "simple.py", line 12, in main
    foo()
NameError: global name 'foo' is not defined

为什么说未定义foo?

为了理解,我尝试像这样使用dir()

In order to understand, I tried using dir() like this

import simple # imports simple.py
dir(simple)

并按预期显示foo已定义.

['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'foo', 'main']

我还注意到,当我在反序列化代码对象上使用dis.dis()时(通过marshal.load()读取),我看到的唯一是LOAD_NAMECALL_FUNCTIONmain(),但是当我像这样用import做到

I've also noticed that when I use dis.dis() on the deserialized code object (read via marshal.load()), the only thing I see is the LOAD_NAME and CALL_FUNCTION for main(), but when I do it with import like this

import dis, sys

import simple
dis.dis(sys.modules["simple"])

它给了我如预期的整个拆卸过程.

it gives me the entire disassembly as expected.

我什至看过 python使用的一些代码进行编译,尽管我认为import使用某种查找表进行定义,但我不确定compile()与导致这种行为的区别是什么.

I've even looked at some of the code that python uses for compiling and although I think import uses some sort of lookup table for definitions, I'm not sure what the difference is with compile() that's causing this behavior.

推荐答案

此脚本成功地练习了您的simple.py代码3次.这澄清了什么吗?还是我误会了你的问题?

This script successfully exercises your simple.py code 3 times. Does this clarify anything? Or am I misunderstanding your question?

# from original example
with open('simple.py', 'r') as f:
    code = f.read()
exec(code)
# compile and run again
a = compile(code, "simple_compiled_this_file_not_created", "exec")
exec(a)
# marshal and unmarshal
import marshal
f = open("./marshalfoo.bin", "wb")
marshal.dump(a,f) 
f.close()
b = marshal.load(open("./marshalfoo.bin", "rb"))
exec(b)

这篇关于为什么在编组代码上调用exec的函数会给出关于全局变量的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆