Подтвердить что ты не робот

Python: получить вывод печати в инструкции exec

У меня есть небольшая проблема. Вот мой код:

code = """
i = [0,1,2]
for j in i :
    print j
"""
result = exec(code)

Как я могу получить то, что напечатал вывод? Как я могу получить что-то вроде:

0
1
2

С уважением и благодарностью,

4b9b3361

Ответ 1

У меня была такая же идея, как и Frédéric, но я написал диспетчер контекста для работы с заменой 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()

Ответ 2

Вы можете перенаправить стандартный вывод на строку в течение времени вызова 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()

Ответ 3

Вот Py3-friendly версия ответа @Jochen. Я также добавил предложение 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())

Ответ 4

Вот небольшая коррекция ответа Фредерика. Нам нужно обработать возможное исключение в 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

Ответ 5

Что-то вроде:

 codeproc = subprocess.Popen(code, stdout=subprocess.PIPE)
 print(codeproc.stdout.read())

должен выполнить код в другом процессе и передать результат обратно в вашу основную программу через codeproc.stdout. Но я лично не использовал его, поэтому, если что-то я сделал неправильно, не стесняйтесь указать на это: P