问题描述
考虑以下脚本,该脚本使用exec
定义两个函数,其中一个调用另一个函数:
def run_code():
code = """
def foo():
print('foo')
return 1
def bar():
print('bar calls foo')
return 1 + foo()
result = bar()
"""
exec(code,globals(),locals())
print('Result: {}'.format(locals()['result']))
run_code()
我希望看到以下输出:
bar calls foo
foo
Result: 2
但是,相反,我得到以下输出+ stacktrace:
bar calls foo
Traceback (most recent call last):
File "minimal.py",line 17,in <module>
run_code()
File "minimal.py",line 14,in run_code
exec(code,locals())
File "<string>",line 10,in <module>
File "<string>",line 8,in bar
NameError: name 'foo' is not defined
有趣的是,如果将run_code
的内容移到模块级别,则可以正常工作。但是,如果我随后用新的空字典替换globals()
或locals()
,它将再次中断。我还知道,将def foo
放入bar
的身体中将使其正常工作。
(我知道exec
通常不被接受。我有充分的理由使用它。)
解决方法
如果提供的话,本地变量可以是任何映射对象。记住在模块 级别,全局变量和本地变量是同一词典。如果高管得到两个 将对象作为全局对象和局部对象分开,代码将作为 如果它嵌入在类定义中。
并且类定义不会创建封闭范围,请注意,这就是为什么不使用time_dict = {
"CS101": {
"Time": "8:00 a.m."
},"CS102": {
"Time": "9:00 a.m."
},"CS103": {
"Time": "10:00 a.m."
},"NT110": {
"Time": "11:00 a.m."
},"CM241": {
"Time": "1:00 p.m."
},}
不能从另一个方法调用一个方法的原因。因此 just 通过self
字典。或将两个相同的dict传递给两个参数。
globals()
,
cout<<"\n\n*The game is being played*\n\n"<<endl;
cout<<"Guess the number between 1 to 100\n"<<endl;
while(true)
{
cout<<"Input number:";
int maxNum = 100;
int leastNum = 1;
int guess;
cin>>guess;
if(guess < leastNum || guess > maxNum)
{
cout<<"It must be higher or equal than"<<" "<<leastNum<<endl<<"and it must not exceed"<<" "<<maxNum<<endl;
}
else if(guess < RanNum)
{
cout<<"\nYour number is LOW\n"<<endl;
}
else if(guess > RanNum)
{
cout<<"\nYour number is HIGH\n"<<endl;
}
else
{
cout<<"\nYour correct!";
again();
break;
}
}
}
int main()
{
int choice;
cout<<"Want to play the game?\n\n"<<endl;
cout<<"Type 1 if want to play"<<endl<<"Type 0 if not\n\n"<<endl;
cout<<"Input here:";
cin>>choice;
switch(choice)
{
case 1 :
play_game();
break;
case 0 :
cout<<"\nOh ok see ya!\n\n";
break;
default :
cout<<"\n\nThe choices are\n\n1 or 0 \n\nplease try again\n\n";
break;
}
return 0;
}
输出:
code = """
def foo():
print('foo')
return 1
def bar():
global foo;
print('bar calls foo')
return 1 + foo()
result = bar()
"""
def run_code():
exec(code,globals(),locals())
print('Result: {}'.format(locals()['result']))
run_code()