我正在使用RestrictedPython
运行以下代码(使用safeglobals['_print_'] = PrintCollector
和compile_restricted_exec
/ exec(compiled_code, safe_globals, locals)
)。
def foo():
print 'bar'
print '123'
foo()
执行代码后,我可以通过locals.pop('_print')
获取打印输出,PrintCollector
包含print '123'
的实例,但仅适用于函数外部的PrintCollector
语句。在调试时,我看到正在创建两个print
实例,大概是在使用PrintCollector
语句的两个上下文(模块级别和函数)中。
但是,我找不到一种方法来访问在输入def foo()
时创建的RestrictedPython
实例。 RestrictedPython
的文档很少,这就是为什么我在这里询问有关如何访问函数的打印输出from RestrictedPython import compile_restricted
from RestrictedPython.PrintCollector import PrintCollector
_print_ = PrintCollector
code_string = """
def foo():
print 'bar'
print '123'
foo()
"""
loc = {'_print_': PrintCollector, '_getattr_': getattr}
compiled_code = compile_restricted(code_string, '<string>', 'exec')
exec(compiled_code, loc)
loc['_print']()
-way的任何建议。
例:
from RestrictedPython import compile_restricted
from RestrictedPython.PrintCollector import PrintCollector
_print_ = PrintCollector
code_string = """
def foo():
global debug_inner
debug_inner = 'bar'
foo()
debug_outer = '123'
results = [debug_inner, debug_outer]
"""
compiled_code = compile_restricted(code_string, '<string>', 'exec')
exec(compiled_code)
print results
# Output should be:
# >>> ['bar', '123']
更新:以下是我在不使用print-statements的情况下调试受限代码的方法:
printed
老答案:
按照您给出的示例,函数需要返回https://code.activestate.com/pypm/restrictedpython/#print变量,并且还要在print语句中执行,如这些文档中所述:from RestrictedPython import compile_restricted
from RestrictedPython.PrintCollector import PrintCollector
_print_ = PrintCollector
code_string = """
def hello_world():
print 'Hello inner world!'
return printed
print 'Hello outer world!' # print a string
print hello_world() # print return of function
results = printed # fetch printed in a global
"""
# Compile and excecute restricted code:
compiled_code = compile_restricted(code_string, '<string>', 'exec')
exec(compiled_code)
# Now we have `results` available as a global:
print results.split('\n') # convert string into list of lines
# We should get:
# >>> ['Hello inner world!', 'Hello outer world!', '', '']
例:
def singleton(cls):
_instance = {}
def inner(t):
if cls not in _instance:
_instance[cls] = cls(t)
return _instance[cls]
return inner
@singleton
class SafePrintCollector(PrintCollector):
pass
我遇到了同样的问题,我发现也有两个PrintCollector实例被创建。
所以我继承了PrintCollector类并使其成为单例。问题解决了。
qazxswpoi
但是,如果要多次运行RestrictedPython,则需要添加重置方法以清除上次打印输出。