gpt4 book ai didi

python - 为什么我在编码代码上调用 exec 的函数会给出有关全局的错误?

转载 作者:太空狗 更新时间:2023-10-29 21:12:09 24 4
gpt4 key购买 nike

在玩弄 compile() 时, the marshal module , 和 exec .我遇到了一些令人困惑的行为。考虑 simple.py

def foo():
print "Inside foo()..."

def main():
print "This is a simple script that should count to 3."

for i in range(1, 4):
print "This is iteration number", i

foo()

if __name__ == "__main__":
main()

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

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()像这样

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")

它打印预期输出的开头,然后出错

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()像这样

import simple # imports simple.py
dir(simple)

正如预期的那样,它显示foo已定义。

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

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

import dis, sys

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

它按预期给了我整个反汇编。

我什至看过some of the code that python uses for compiling虽然我认为import使用某种查找表来定义,我不确定与 compile() 有什么区别这导致了这种行为。

最佳答案

此脚本成功运行了您的 simple.py 代码 3 次。这说明了什么吗?还是我误解了你的问题?

# 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)

关于python - 为什么我在编码代码上调用 exec 的函数会给出有关全局的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12180627/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com