warnings.warn () vs. logging.warning ()

80

Was ist der Unterschied zwischen warnings.warn()und logging.warn()in Bezug auf das, was sie tun und wie sie verwendet werden sollten?

Hekevintran
quelle
6
Würden Sie bitte Ihre akzeptierte Antwort hier ändern?
Antti Haapala

Antworten:

-2

Einer löst eine Ausnahme aus, die nach Bedarf abgefangen oder ignoriert werden kann, und der andere fügt optional einen Eintrag zum Protokoll hinzu, der auf der aktuellen Protokollierungsstufe basiert. Eine sollte verwendet werden, wenn einer vor verschiedenen Dingen im Code warnt, und die andere sollte bei der Protokollierung verwendet werden.

Ignacio Vazquez-Abrams
quelle
21
Soweit ich weiß, ist die akzeptierte Antwort falsch. Weder Warnungen noch Protokollierung lösen eine Ausnahme aus. Aber Nachrichten drucken. Sie haben jedoch eine andere Systematik (es ist jedoch möglich, Warnungen über in die Protokollierung zu integrieren logging.captureWarnings()). Warnmeldungen werden standardmäßig nur einmal angezeigt, wie @cxrodgers erklärte, um den Benutzer anzuweisen, seinen Code zu ändern. Wenn Sie sich auf der anderen Seite anmelden und alle Warnungen dokumentieren, können Sie jedoch konfigurieren, was im Detail angezeigt werden soll. Warnungen können mit "-W error" zu Ausnahmen ausgelöst werden.
DerWeh
80

Ich stimme der anderen Antwort zu - loggingdient der Protokollierung und der warningWarnung -, möchte aber weitere Details hinzufügen.

Hier ist eine Anleitung im Tutorial-Stil, die Sie durch die Schritte zur Verwendung des loggingModuls führt. https://docs.python.org/3/howto/logging.html

Es beantwortet direkt Ihre Frage:

warnings.warn () im Bibliothekscode, wenn das Problem vermeidbar ist und die Clientanwendung geändert werden sollte, um die Warnung zu beseitigen

logging.warning () Wenn die Clientanwendung nichts gegen die Situation unternehmen kann, sollte das Ereignis dennoch notiert werden

cxrodgers
quelle
58

logging.warningProtokolliert einfach etwas auf der WARNINGEbene, genauso wie es logging.infoauf der INFOEbene und logging.errorauf der ERROREbene protokolliert . Es hat kein besonderes Verhalten.

warnings.warnGibt eine aus Warning, die gedruckt stderr, vollständig ignoriert oder wie eine normale ExceptionDatei ausgelöst werden kann (was möglicherweise zum Absturz Ihrer Anwendung führt), abhängig von der genauen Warningausgegebenen Unterklasse und der Konfiguration Ihres Warnfilters . Standardmäßig werden Warnungen gedruckt stderroder ignoriert.

Von ausgegebene Warnungen warnings.warnsind oft nützlich, aber leicht zu übersehen (insbesondere, wenn Sie ein Python-Programm in einem Hintergrundprozess ausführen und nicht erfassen stderr). Aus diesem Grund kann es hilfreich sein, sie protokollieren zu lassen.

Python bietet eine integrierte Integration zwischen dem loggingModul und dem warningsModul, damit Sie dies tun können. Rufen Sie einfach logging.captureWarnings(True)zu Beginn Ihres Skripts auf und alle vom warningsModul ausgegebenen Warnungen werden automatisch auf der Ebene protokolliert WARNING.

Mark Amery
quelle
26

Neben der kanonischen Erklärung in der offiziellen Dokumentation

warnings.warn () im Bibliothekscode, wenn das Problem vermeidbar ist und die Clientanwendung geändert werden sollte, um die Warnung zu beseitigen

logging.warning () Wenn die Clientanwendung nichts gegen die Situation unternehmen kann, sollte das Ereignis dennoch notiert werden

Es ist auch erwähnenswert, dass standardmäßig warnings.warn("same message")nur einmal angezeigt wird. Das ist ein großer spürbarer Unterschied. Zitiert aus dem offiziellen Dokument

Wiederholungen einer bestimmten Warnung für denselben Quellspeicherort werden normalerweise unterdrückt.

>>> import warnings
>>> warnings.warn("foo")
__main__:1: UserWarning: foo
>>> warnings.warn("foo")
>>> warnings.warn("foo")
>>>
>>> import logging
>>> logging.warn("bar")
WARNING:root:bar
>>> logging.warn("bar")
WARNING:root:bar
>>> logging.warn("bar")
WARNING:root:bar
>>>
>>>
>>> warnings.warn("fur")
__main__:1: UserWarning: fur
>>> warnings.warn("fur")
>>> warnings.warn("fur")
>>>
RayLuo
quelle
1
Beachten Sie, dass "Nur einmal anzeigen" das beabsichtigte Standardverhalten ist. Warnfilter können dies jedoch ändern.
Gerrit