我正在使用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']()
答案 0 :(得分:1)
更新:这是不使用打印语句调试受限代码的方法:
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']
旧答案:
按照您给出的示例,该函数需要返回printed
变量,并且还必须在打印语句中执行,如以下文档所述:
https://code.activestate.com/pypm/restrictedpython/#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!', '', '']
答案 1 :(得分:0)
我遇到了同样的问题,并且发现也创建了两个PrintCollector实例。
因此,我继承了类PrintCollector并将其设为单例。问题解决了。
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
但是,如果要多次运行RestrictedPython,则需要添加一个reset方法来清除最后的打印输出。