0

私は次のようにコードを実行しています(他のトピックからコピーして追加しましたsleep):

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 = """
import time
i = [0,1,2]
for j in i :
    print j
    time.sleep(5)
"""
with stdoutIO() as s:
    exec code

print "out:", s.getvalue()

このコードを実行すると、プログラムが終了して出力が表示されるまで15秒待つ必要があります。しかし、5秒ごとprintのループの各反復でステートメントの出力を確認するにはどうすればよいですか?for出力全体を確認するために15秒待たないでください。

これは可能ですか?execの現在の出力を確認することは可能ですか?

4

2 に答える 2

1

In the code you've posted, the context manager will yield only once when the with is executed. So the code has to execute first (all 15 seconds of it) and all the code output is stored within the StringIO object. Hence, with such code, you cannot obtain output as it is written.

If you want to output on the fly, you need to provide your own file-like class instead of StringIO and override the write method. For example (example only, very quick and dirty code):

import sys
import StringIO
import contextlib

class Proxy(object):
    def __init__(self,stdout,stringio):
        self._stdout = stdout
        self._stringio = stringio
    def __getattr__(self,name):
        if name in ('_stdout','_stringio','write'):
            object.__getattribute__(self,name)
        else:
            return getattr(self._stringio,name)
    def write(self,data):
         self._stdout.write(data)
         self._stringio.write(data)

@contextlib.contextmanager
def stdoutIO(stdout=None):
    old = sys.stdout
    if stdout is None:
        stdout = StringIO.StringIO()
    sys.stdout = Proxy(sys.stdout,stdout)
    yield sys.stdout
    sys.stdout = old

code = """
import time
i = [0,1,2]
for j in i :
    print j
    time.sleep(5)
"""

with stdoutIO() as s:
    exec code

print "out:", s.getvalue()

which outputs:

0
1
2
out: 0
1
2

The first three lines are printed at 5 seconds intervals. The last three in one go at the end.

于 2013-02-05T13:27:45.513 に答える
1

問題は exec とは関係ありません。問題は、stdout を にリダイレクトしたことに関係していますStringIO。すべての印刷ステートメントはStringIO、画面に印刷する代わりにコンテンツを追加しています。したがって、出力は表示されません。画面に何かを出力する唯一の行は

print "out:", s.getvalue()

これは、15 秒間の睡眠後に発生します。


with stdoutIO() as s:
    ...

にリダイレクトstdoutStringIO.StringIOます。withコンテキストが完了した後でのみ、端末に出力されるstdout元の にリダイレクトされます。sys.stdout


したがって、print ステートメントが発生したときに exec から出力を取得するには、stdeoutIOコンテキスト マネージャーを削除するだけです。

import sys

code = """
import time
i = [0,1,2]
for j in i :
    print j
    time.sleep(5)
"""

exec code
于 2013-02-05T13:25:17.733 に答える