这个标题看起来很愚蠢,但我不知道如何准确地表达它,对不起。
我有一个程序,需要评估一些用户代码(通过RestrictedPython的安全性),我想把一个函数放在评估的全局变量中,这样当评估时,它可以打印出一些调试信息给我,例如(简化):
class UserException(Exception):
pass
def err(msg):
# ? how to get the globals variable in eval ?
A = globals().get('A', 'A not found')
return UserException("%s and A's value is %r" % (msg, A))
g = {
'err': err,
'A': None,
'__builtins__': {},
}
print eval('A or err("A not true")', g)这将给出结果:
A not true and A's value is 'A not found'在这里使用'globals()‘加上'err’当然是错误的。但是我怎样才能在'err‘里面得到'g’的值呢?
发布于 2012-09-21 18:30:00
从函数内部对globals()的任何引用都会给出定义函数时在作用域中的全局变量。您在这里看到的与将函数从一个模块导入到另一个模块时没有什么不同:导入的函数仍然引用定义它的模块的全局变量。
要让函数使用g作为其globals(),最简单的方法是使用g作为全局变量来执行定义。如果您确实更改了函数的全局变量,那么不要模糊,还需要包括函数使用的任何其他全局变量;在本例中为UserException。
或者,您可以让err()检查其调用方的堆栈框架,并使用调用方的全局变量。这是混乱的,但如果是为了调试,信息可能是您可以接受的。
>>> def err(msg):
# ? how to get the globals variable in eval ?
A = sys._getframe(1).f_globals.get('A', 'A not found')
return UserException("%s and A's value is %r" % (msg, A))
>>> import sys
>>> g = {
'err': err,
'A': None,
'__builtins__': {},
}
>>> print eval('A or err("A not true")', g, g)
A not true and A's value is None
>>> 发布于 2012-09-21 17:18:16
您可以将其作为默认参数传递给g:
def err(msg, g=g):
A = g['A']
return UserException("%s and A's value is %r" % (msg, A))将给出结果:A not true and A's value is None。
https://stackoverflow.com/questions/12527525
复制相似问题