2012-01-08 16 views
8

すべての印刷文を端末とファイルの両方に出力する必要があります。 は、私は私がファイルとプリントだけ端末にだ、通常の動作に戻って書き込みを停止したいときstdoutを元に戻すことができません(端末のみ)

私の問題はあるので、私は

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

sys.stdout = Tee("log.txt") 

が素晴らしい作品を使用this stackoverflow question で解決策を見つけました
del(sys.stdout)を使用してdelメソッドを呼び出そうとしました。
私もへの最後の行を変更しようとしました:、まだ端末とファイルに書き込ま印刷のさらなる用途を

multiple_print = Tee("log.txt") 
    sys.stdout = multiple_print 

とデル(multiple_print)を使用するよりもとにかかわらず、私が試したものを

を失敗しましたどちらも。

アイデア?

答えて

12

あなたは再割り当てする前に、元のファイル記述子への参照を保存する必要があります。

oldstdout = sys.stdout 

、その後sys.stdoutにそれを再割り当てします!

delステートメントは__del__を直接呼び出すのではなく、オブジェクトの参照カウンタを減らします。参照カウンタがゼロになってオブジェクトが破棄されようとしている場合は、__del__メソッドが呼び出されます。だから、あなたが__del__メソッドを呼び出すためには、ガベージコレクタに任されているので、再割り当てを強制することはできません。

あなたが直接sys.stdoutの変数を再割り当てする必要があります。

試してみてください。

sys.stdout = sys.__stdout__ 
+0

感謝。私は複雑な解決策を働かせて、基本を忘れさせようとしています。しかし、__del__が機能していない理由を知っていますか? (sys.stdout = self.stdoutが__init__部分に保存されています) –

+11

[sys .__ stdout__](http://docs.python.org/library/sys.html#sys.__stdout__)古い参照を自分で保存する代わりに。 –

+0

あなたのフォローアップに対応するために私の答えが更新されました!フレデリック・ハミディにはポイントがあります!私は 'sys .__ stdout__'について知らなかった! –

関連する問題