13

filePythonの組み込みクラスをサブクラス化して、とにいくつかの機能を追加しようとしてstdinいますstdout。これが私がこれまでに持っているコードです:

class TeeWithTimestamp(file):
    """
    Class used to tee the output of a stream (such as stdout or stderr) into
    another stream, and to add a timestamp to each message printed.
    """

    def __init__(self, file1, file2):
        """Initializes the TeeWithTimestamp"""
        self.file1 = file1
        self.file2 = file2
        self.at_start_of_line = True

    def write(self, text):
        """Writes text to both files, prefixed with a timestamp"""

        if len(text):
            # Add timestamp if at the start of a line; also add [STDERR]
            # for stderr
            if self.at_start_of_line:
                now = datetime.datetime.now()
                prefix = now.strftime('[%H:%M:%S] ')
                if self.file1 == sys.__stderr__:
                    prefix += '[STDERR] '
                text = prefix + text

            self.file1.write(text)
            self.file2.write(text)

            self.at_start_of_line = (text[-1] == '\n')

目的は、各メッセージの先頭にタイムスタンプを追加し、すべてをログファイルに記録することです。しかし、私が遭遇する問題は、これを行うと次のようになることです。

# log_file has already been opened
sys.stdout = TeeWithTimestamp(sys.stdout, log_file)

それから私がやろうとするとprint 'foo'、私はを取得しValueError: I/O operation on closed fileます。新しいファイルを開きたくないので、意味のある呼び出しを行うことができません。また、読み取り専用の属性であるため、割り当てることfile.__init__()もできません。__init__()self.closed = False

print 'foo'これを変更して、すべての標準file属性とメソッドをサポートできるようにするにはどうすればよいですか?

4

2 に答える 2

12

呼び出しは非常に実行可能ですが(たとえば、'/ dev / null'で)、のオーバーライドの試行はステートメントの目的で「取得」されないため、file.__init__実際の使用はありません。のインスタンス(そして継承することであなたはそうしました)。writeprintfile.writesys.stdoutfile

print以外のメソッドは実際には必要ないため、クラスをではなくwriteから継承させることができます。objectfile

他のファイルメソッドが必要な場合(つまり、print実行しているのがすべてではない場合)、それらを自分で実装することをお勧めします。

于 2009-07-04T19:17:03.017 に答える
3

次の使用を避けることもできますsuper

class SuperFile(file):

    def __init__(self, *args, **kwargs):
        file.__init__(self, *args, **kwargs)

あなたはそれで書くことができるでしょう。

于 2010-03-20T17:55:21.543 に答える