8

loggingモジュールとprintステートメントを使用するプログラムがあります。ロギングは、プログラムが何をしているかをユーザーに通知することです。たとえば、

logging.info("downloading HTML")
time.sleep(1)
logging.info("parsing HTML")
time.sleep(1)
print "the result"

最後に、画面上の出力 (stdout と stderr の混合) は次のようになります。

INFO:downloading HTML
INFO:parsing HTML
the result

次のログ出力が表示されたとき、または印刷が呼び出されたときに、最後のログ出力を非表示にしたいと考えています。たとえば、プログラムを開始すると、次のように表示されます。

INFO:download HTML

1 秒待つ"parsing HTML"と、前の情報が次の情報に置き換え"downloading HTML"られるため、画面には次の情報のみが表示されます。

INFO:parsing HTML

前に他に何もない場合は、1 秒待ってください。画面にのみ表示したい:

"the result"

この機能は、stderr にログオンするときにのみ必要であり、たとえば、ファイルにログを記録するときではなく、すべてのlogging出力を確認したいのです。

出来ますか?

4

1 に答える 1

13

UNIXライクな端末では、テキストの前にANSIエスケープシーケンスを追加してみることができます。

import time
import sys

print 'this is a text',
sys.stdout.flush()

time.sleep(1)
print '\x1b[80D'+'\x1b[K'+'Second text',
sys.stdout.flush()

文字'\x1b'はエスケープ文字です。最初のシーケンスでは、カーソルが最大80位置左に移動します。2番目はラインをクリアします。

printステートメントが2行目に移動しないようにするには、printステートメントの最後にコンマが必要です。stdout次に、ストリームをフラッシュする必要があります。そうしないと、テキストが表示されません。

編集:これをロギングと組み合わせるには、単純な関数でラップします。

def mylog(text):
    logging.info(text)
    print '\x1b[80D' + '\x1b[K'+ text,
    sys.stdout.flush()

編集2:これを標準のロギングに統合します。

import logging
# create console handler
ch = logging.StreamHandler()
# create formatter
formatter = logging.Formatter('\x1b[80D\x1b[1A\x1b[K%(message)s')
# add formatter to console handler
ch.setFormatter(formatter)
# add console handler to logger
logger.addHandler(ch)

ロギングモジュールはそれ自体で改行を追加するように見えるので、ANSIシーケンス(\ x1b [1A)を追加して1行上に移動しました。

詳細については、ロギングのハウツーも参照してください。

于 2012-08-16T11:45:09.623 に答える