У меня маленькая проблема. Вот мой код:
code = """ i = [0,1,2] for j in i : print j """ result = exec(code)
Как я могу получить вещи, которые печатаются? Как я могу получить что-то вроде:
0 1 2
С уважением и благодарностью
У меня была та же идея, что и у Фредерика, но я написал менеджер контекста для обработки замены stdout:
import sys import StringIO import contextlib @contextlib.contextmanager def stdoutIO(stdout=None): old = sys.stdout if stdout is None: stdout = StringIO.StringIO() sys.stdout = stdout yield stdout sys.stdout = old code = """ i = [0,1,2] for j in i : print j """ with stdoutIO() as s: exec code print "out:", s.getvalue()
Вы можете перенаправить стандартный вывод в строку на время вызова exec:
code = """ i = [0,1,2] for j in i : print j """ from cStringIO import StringIO old_stdout = sys.stdout redirected_output = sys.stdout = StringIO() exec(code) sys.stdout = old_stdout print redirected_output.getvalue()
Вот Py3-дружественная версия ответа @ Jochen.Я также добавил условие try-except для восстановления в случае ошибок в code.
try-except
code
import sys from io import StringIO import contextlib @contextlib.contextmanager def stdoutIO(stdout=None): old = sys.stdout if stdout is None: stdout = StringIO() sys.stdout = stdout yield stdout sys.stdout = old code = """ i = [0,1,2] for j in i : print(j) """ with stdoutIO() as s: try: exec(code) except: print("Something wrong with the code") print("out:", s.getvalue())
Вот небольшое исправление ответа Фредерика. Нам нужно обработать возможное исключение в exec(), чтобы вернуть нормальное stdout. В противном случае мы не могли бы видеть дальше print выходы:
exec()
stdout
print
code = """ i = [0,1,2] for j in i : print j """ from cStringIO import StringIO old_stdout = sys.stdout redirected_output = sys.stdout = StringIO() try: exec(code) except: raise finally: # ! sys.stdout = old_stdout # ! print redirected_output.getvalue() ... print 'Hello, World!' # now we see it in case of the exception above
Что-то вроде:
codeproc = subprocess.Popen(code, stdout=subprocess.PIPE) print(codeproc.stdout.read())
должно выполнить код в другом процессе и передать вывод обратно в вашу основную программу через codeproc.stdout.Но я не использовал это лично, поэтому, если я что-то сделал не так, не стесняйтесь указывать: P
codeproc.stdout