Добавление даты и времени в печать Python - PullRequest
14 голосов
/ 03 февраля 2011

Я пытаюсь отладить поведение большой библиотеки, от которой я зависим, которая использует рассеяние (без всякого изобилия) операторов отладочной печати через множество исходных файлов. Проблема в том, что большинство, если не все эти отладочные операторы печати не содержат отметку даты / времени, поэтому трудно связать сбои на уровне приложения со сбоями в самом коде библиотеки.

Вместо того, чтобы изменять исходный код для всех отладочных отпечатков, предположительно причастных к сбою, который я вижу, я подумал, что возможно обезьяна временно исправит встроенную функцию Python для печати "100" , для того, чтобы весь вывод был префикс с отметкой времени.

Поскольку встроенная печать не является функцией в среде Python 2.6, с которой я работаю, я не знаю, возможно ли это. Если бы кто-то сделал это или достиг аналогичного результата, используя другой прием в Python, я был бы признателен за ваш совет или даже за лучший код для решения этой проблемы.

Ответы [ 3 ]

22 голосов
/ 03 февраля 2011

Поскольку вы не можете переопределить функцию write (она доступна только для чтения), простой обезьян-патч может выглядеть так (добавляя метку времени к каждой напечатанной строке):

old_f = sys.stdout
class F:
    def write(self, x):
        old_f.write(x.replace("\n", " [%s]\n" % str(datetime.now())))
sys.stdout = F()

Пример будет выглядеть так:

>>> print "foo"
foo [2011-02-03 09:31:05.226899]
6 голосов
/ 19 июля 2014

Альтернативное решение, что отметка времени - начало (добавлено) вместо конца (добавлено):

old_out = sys.stdout


class St_ampe_dOut:
    """Stamped stdout."""

    nl = True

    def write(self, x):
        """Write function overloaded."""
        if x == '\n':
            old_out.write(x)
            self.nl = True
        elif self.nl:
            old_out.write('%s> %s' % (str(dt.now()), x))
            self.nl = False
        else:
            old_out.write(x)

sys.stdout = St_ampe_dOut()
0 голосов
/ 12 февраля 2019

Мне не на 100% ясно, как существующий ответ от Велизара обрабатывает случаи, когда вывод отправляется с несколькими \ n.Я не уверен, что это работает надежно, и если это так, я думаю, что это может зависеть от потенциально недокументированного поведения выходных потоков.

Вот мое решение, которое добавляет метку времени в начало каждой напечатанной строки, инадежно обрабатывает несколько строк / строк без \ n:

class TimestampFilter:
    # pending_output stores any output passed to write where a \n has not yet been found
    pending_output = ''
    def write(self, message):
        output = self.pending_output + message
        (output, not_used, self.pending_output) =  output.rpartition('\n')
        if output != '':
            timestamp = time.strftime("%Y-%m-%d %X")
            output = timestamp + " " + output.replace("\n", "\n"+timestamp+" ")
            print(output, file=sys.__stdout__)
            sys.__stdout__.flush()

sys.stdout = TimestampFilter()
...