1

ターミナルとIDLEシェルで機能するように次のコードを取得しようとしています。stdoutを画面とログファイルに分割することを目的としています。

class Tee(object):
    def __init__(self, name, mode):
        self.filename = open(name, mode)
        self.stdout = sys.stdout
        sys.stdout = self
    def __del__(self):
        sys.stdout = self.stdout
        self.filename.close()
    def write(self, data):
        self.stdout.write(data)
        self.filename.write(data)

Tee('logfile.log', 'wb')

print 'test123'

ターミナルからこのコードを実行すると、正常に動作します。IDLEから実行すると、正常に出力されますが、ログファイルにテキストがなく、例外はスローされません。なぜこれはコマンドpromtからは機能するが、IDLEからは機能しないのですか?両方の環境で機能させるにはどうすればよいですか?私はWin7とPython2.7を使用しています。

編集:ステートメントで機能するようにこれをまとめました。それはクラスでの私の最初の亀裂なので、改善のための提案を歓迎します。

newlog = True
class Tee(object):
    def __init__(self, name, mode=''):
        global newlog
        if newlog:
            self.filename = open(name, 'w'+mode)
        else:
            self.filename = open(name, 'a'+mode)
        newlog = False
    def __enter__(self):
        self.stdout = sys.stdout
        sys.stdout = self
        return self
    def __exit__(self, name, mode, data):
        sys.stdout = self.stdout
        self.filename.close()
    def __del__(self):
        try:
            self.filename.close()
            sys.stdout = self.stdout
        except:
            pass
    def startlog(self):
       self.stdout = sys.stdout
       sys.stdout = self
    def stoplog(self):
        self.filename.close()
        sys.stdout = self.stdout 
    def write(self, data):
        self.stdout.write(data)
        self.filename.write(data)
        self.filename.flush()


with Tee('logfile.log', 'b'):
    print 'I am the walrus'

print 'coocoocachoo'

Tee = Tee('logfile.log')
Tee.startlog()
print 'I am the eggman'
Tee.stoplog()

print 'coocoocachoo'
4

1 に答える 1

2

logfile.logは空ではなく、フラッシュされないだけです。試す:

sys.stdout.filename.flush()

あなたができることは、より完全なラッパーを書くことです。アイデア-これをより一般的な方法で行うこともできます(ここで解決する問題がいくつかある可能性があります):

import functools
class Tee(object):
    def __init__(self, name, mode)
    .
    .
    for name in ('write', 'flush', ...):
        setattr(self, name, functools.partial(self._wrapper, name))

    def _wrapper(func_name, *args, **kw):
        getattr(self.filename, name)(*args, **kw)
        getattr(self.stdout, name)(*args, **kw)
于 2013-03-12T17:26:11.047 に答える