Doppelte Ausgabe beim Umleiten von sys.stdout

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Whitie
User
Beiträge: 111
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Doppelte Ausgabe beim Umleiten von sys.stdout

Beitragvon Whitie » Sonntag 28. Januar 2007, 09:15

Hallo Leute,
ich habe ein Problem mit dem Umleiten der Standardausgabe.
Ich habe eine Klasse, die mir das aktuelle Datum vor jede Ausgabe setzen soll (Logging).

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import codecs
from locale import getpreferredencoding
import os
from time import strftime
import sys

ENCODING = getpreferredencoding()

class Log(object):
    '''
    Klasse zum Abfangen der print Anweisungen. Umleitung erfolgt wahlweise
    in eine Datei, auf die Kommandozeile oder beides.
    '''
    def __init__(self, logfile = '', rotate = False, cli = True):
        self.stdout = sys.__stdout__
        self.cli = cli
        if logfile:
            self.log = True
            if rotate:
                self.logfile = '%s_%s.log' % (logfile, strftime('%A'))
            else:
                self.logfile = '%s.log' % logfile
        else:
            self.log = False

    def write(self, *text):
        msg = u' '.join(text)
        date = strftime('%W %Y-%m-%d %H:%M:%S')
        if self.cli:
            self.stdout.write('%s %s' % (date, msg.encode(ENCODING)))
        if self.log:
            logfile = self.logfile
            mode = self._check_size(logfile)
            try:
                f = codecs.open(logfile, mode, 'UTF-8')
                f.write('%s %s' % (date, msg))
            finally:
                f.close()

    def _check_size(self, logfile):
        if os.path.isfile(logfile):
            if os.path.getsize(logfile) > 5000:
                return 'w'
            else:
                return 'a'
        else:
            return 'w'

if __name__ == '__main__':
    sys.stdout = Log('app', True, True)
    print u'Logtest öüä'


Wenn ich dieses Skript ausführe, erhalte ich die folgende Ausgabe:
[code=]04 2007-01-28 08:58:57 Logtest öüä04 2007-01-28 08:58:57[/code]

Nun die Frage: Warum wird das Datum doppelt geschrieben ? Und warum wird am Ende ein newline eingefügt ?
Wenn ich in Zeile 33 date nicht schreibe
[code=python firstline=33]self.stdout.write(msg.encode(ENCODING))[/code]
funktioniert alles wie gewünscht. Es wird der String ausgegeben und kein newline angefügt. Genauso sieht es im Logfile aus.

Gruß, Whitie
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 28. Januar 2007, 10:06

Wenn du dir mal ansiehst, was "msg" ist, siehst du, dass einmal "Logtest" und einmal "\n" ausgegeben wird.

Das liegt am "magischen" Verhalten von `print`, das ja mit "," auch Ausgabe ohne Newline unterstützt.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Re: Doppelte Ausgabe beim Umleiten von sys.stdout

Beitragvon BlackJack » Sonntag 28. Januar 2007, 10:13

Whitie hat geschrieben:Nun die Frage: Warum wird das Datum doppelt geschrieben ? Und warum wird am Ende ein newline eingefügt ?


Weil ``print`` am Ende ein Newline ausgibt, und das anscheinend mit einem eigenen Aufruf von `write()`.

Teste mal das hier:

Code: Alles auswählen

    print 1, 2, 3


Da hast Du dann viermal das Datum in der Ausgabe ─ einmal für jede Zahl und einmal für den Zeilenwechsel.
Benutzeravatar
Whitie
User
Beiträge: 111
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Beitragvon Whitie » Sonntag 28. Januar 2007, 10:21

Danke erstmal,
ich werde mal in Ruhe testen.

Gruß, Whitie

Wer ist online?

Mitglieder in diesem Forum: Google [Bot]