Перенаправление вывода Python в файл печатает две строки - PullRequest
1 голос
/ 12 декабря 2011

Используя совет другого вопроса о переполнении стека, я написал свой собственный класс LogWriter:

class LogWriter:
    def __init__(self, output, filename):
            self.output = output
            self.logfile = file(filename, 'a')

    def write(self, text):
            now = datetime.now()
            stamp = now.strftime("%Y-%m-%d - %I:%M:%S")
            text = "[%s] %s" % (stamp,text)
            if(DEBUG):
                    self.output.write(text)
                    self.output.flush()
            self.logfile.write(text)
            self.logfile.flush()

    def close(self):
            self.output.close()
            self.logfile.close()

Однако вот что я получаю:

    >>logwriter = LogWriter(sys.stdout, LOG_FILENAME)
    >>sys.stdout = logwriter
    >>print "test"
    [2011-12-12 - 08:15:00] test[2011-12-12 - 08:15:00]

Если я удаляю строку, которая изменяет текст, и печатает только исходное сообщение, класс работает как положено, печатая как в файл журнала, так и в стандартный вывод:

test

По какой-то причине моя временная метка дублирована, и я не могу понять, почему. Как правильно исправить эту ошибку в Python?

РЕДАКТИРОВАТЬ: Как сказал AIX ниже, я предполагал, что вызовы на печать и вызовы на запись были однозначными, но это не так. В качестве простого исправления для продолжения использования моего класса LogWriter я теперь делаю вызовы следующим образом:

...
def write(self, text):
            now = datetime.now()
            stamp = now.strftime("%Y-%m-%d - %I:%M:%S")
            text = "[%s] %s\n" % (stamp,text)
...
>>logwriter = LogWriter(sys.stdout, LOG_FILENAME)
>>logwriter.write("test")
[2011-12-12 - 08:38:55] test

Ответы [ 2 ]

4 голосов
/ 12 декабря 2011

Попробуйте:

>>>print "test",

Возможно, вы получаете неявный символ новой строки от print в качестве отдельного вызова write().В любом случае, проблема в том, что вы получаете несколько вызовов на write() (так как нет гарантии, что вызывающий абонент использует write() - он может вызывать его для каждого символа, если ему нравится).

2 голосов
/ 12 декабря 2011

Не следует предполагать, что один оператор print приводит к одному вызову write().Поэтому я считаю, что весь подход к созданию отметки времени на каждом write() имеет недостатки.

Вы можете попытаться исправить это, создав отметку времени в начале каждой строки (просмотревдля \n символов в text), но мне это не кажется особенно элегантным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...