Windows 10,Python 3.5.1 x64此处。
这很奇怪......让我说我有这个名为do.py
的脚本。请注意import string
声明:
import string
# Please note that if the print statement is OUTSIDE 'main()', it works.
# It's like if 'main()' can't see the imported symbols from 'string'
def main():
print(string.ascii_lowercase)
main()
我想从一个"启动器脚本",在子线程中运行它,就像这样(launcher.py
):
import sys
import threading
sys.argv.append('do.py')
def run(script, filename):
exec(compile(script, filename, 'exec'))
with open(sys.argv[1], 'rb') as _:
script = _.read()
# But this WORKS:
# exec(compile(script, sys.argv[1], 'exec'))
thread = threading.Thread(name='Runner', target=run, args=(script, sys.argv[1]))
thread.start()
thread.join()
它因以下错误而死:
Exception in thread Runner:
Traceback (most recent call last):
File "C:\Program Files\Python35\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "C:\Program Files\Python35\lib\threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "tmpgui.py", line 7, in run
exec(compile(script, filename, 'exec'))
File "do.py", line 6, in <module>
main()
File "do.py", line 4, in main
print(string.ascii_lowercase)
NameError: name 'string' is not defined
也就是说,执行代码未正确导入string
或类似内容,并且main()
string
模块中不可见。
这不是我的项目的完整代码,这个代码太大了,不能在这里发布,但是我创建的最小代码模仿了这个问题。
为了防止有人好奇,我正在重写我的旧程序,该程序导入了脚本的main()
函数并运行该函数,标准输出流重定向到tkinter
文本框。我想加载脚本并运行它,而不是从脚本中导入函数。出于各种原因,我不想使用subprocess
,我更喜欢运行&#34;重定向&#34;代码在线程中并与主线程进行通信,主线程是处理GUI的主线程。这部分工作得很好,我唯一的问题就是这个,我无法理解为什么会发生这种情况!
我最好的选择:我应该将全球或本地词典中的内容传递给exec
,但我在这里丢失了......
提前多多感谢!
答案 0 :(得分:3)
exec(thing, globals(), locals())
相当于run
。
因此,
import string
函数的本地符号表 run
导入模块并将其绑定到本地空间中的变量,该变量是def run(script, filename):
try:
exec(compile(script, filename, 'exec'))
finally:
assert 'string' in locals(), "won't fail because 'import' worked properly"
函数的本地空间。您可以验证这一点:
main
string
有一个单独的本地范围,但它与 do.py 共享全局符号表,因此与 launcher.py 共享。
Python试图在main
的本地(它是空的)和全局符号表中找到名为NameError
的变量,但是失败了,并引发了exec
。
在调用def run(script, filename):
exec(compile(script, filename, 'exec'), {})
时传递一个空字典:
%{
#include "y.tab.h"
#include "Expression.h"
%}
%%
"==" {return EQ;}
"<" {return '<';}
">" {return '>';}
"=" {return '=';}
"+" {return '+';}
"-" {return '-';}
"*" {return '*';}
"/" {return '/';}
"," {return ',';}
";" {return ';';}
"(" {return '(';}
")" {return ')';}
"{" {return '{';}
"}" {return '}';}
"[" {return '[';}
"]" {return ']';}
"int" {return INT;}
"char" {return CHAR;}
"float" {return FLOAT;}
"long" {return LONG;}
"double" {return DOUBLE;}
"return" {return RETURN;}
"if" {return IF;}
"else" {return ELSE;}
[0-9]+ {return Number;}
[A-Za-z][A-Za-z0-9]* {return Identifier;} }
[ \t] ;
[\n] ;
"." {return BADTOKEN;}
%%