您可以将stdout /
stderr重定向到myfunc()中的StringIO,然后将写入该StringIO的所有内容发送回父级(如unutbu所建议)。
由于该示例的功能超出了您的需要,因此以下版本更符合您的既定目标:
#!/usr/bin/env pythonimport sysfrom cStringIO import StringIOfrom pre import InteractiveConsolefrom contextlib import contextmanagerfrom multiprocessing import Process, Pipe@contextmanagerdef std_redirector(stdin=sys.stdin, stdout=sys.stdin, stderr=sys.stderr): tmp_fds = stdin, stdout, stderr orig_fds = sys.stdin, sys.stdout, sys.stderr sys.stdin, sys.stdout, sys.stderr = tmp_fds yield sys.stdin, sys.stdout, sys.stderr = orig_fdsclass Interpreter(InteractiveConsole): def __init__(self, locals=None): InteractiveConsole.__init__(self, locals=locals) self.output = StringIO() self.output = StringIO() def push(self, command): self.output.reset() self.output.truncate() with std_redirector(stdout=self.output, stderr=self.output): try: more = InteractiveConsole.push(self, command) result = self.output.getvalue() except (SyntaxError, OverflowError): pass return more, resultdef myfunc(conn, commands): output = StringIO() py = Interpreter() results = "" for line in commands.split('n'): if line and len(line) > 0: more, result = py.push(line + 'n') if result and len(result) > 0: results += result conn.send(results) conn.close()if __name__ == '__main__': parent_conn, child_conn = Pipe() commands = """print "[42, None, 'hello']"def greet(name, count): for i in range(count): print "Hello, " + name + "!"greet("Beth Cooper", 5)fugaziprint "Still going..."""" p = Process(target=myfunc, args=(child_conn, commands)) p.start() print parent_conn.recv() p.join()有关安全性的通常警告适用于此(即,除非您可以相信这些代码段的发送者不要做任何愚蠢/恶意的操作,否则请不要这样做。)
另请注意,如果您不需要解释python表达式 和 语句的任意组合,则可以简化很多操作。如果只需要调用生成某些输出的顶级函数,则可能更合适:
def dosomething(): print "Doing something..."def myfunc(conn, command): output = StringIO() result = "" with std_redirector(stdout=output, stderr=output): try: eval(command) result = output.getvalue() except Exception, err: result = repr(err) conn.send(result) conn.close()if __name__ == '__main__': parent_conn, child_conn = Pipe() command = "dosomething()" p = Process(target=myfunc, args=(child_conn, command)) p.start() print parent_conn.recv() p.join()



