warnings.warn() vs. logging.warning()
What is the difference between warnings.warn()
and logging.warn()
in terms of what they do and how they should be used?
I agree with the other answer -- logging
is for logging and warning
is for warning -- but I'd like to add more detail.
Here is a tutorial-style HOWTO taking you through the steps in using the logging
module.
https://docs.python.org/3/howto/logging.html
It directly answers your question:
warnings.warn() in library code if the issue is avoidable and the client application should be modified to eliminate the warning
logging.warning() if there is nothing the client application can do about the situation, but the event should still be noted
logging.warning
just logs something at the WARNING
level, in the same way that logging.info
logs at the INFO
level and logging.error
logs at the ERROR
level. It has no special behaviour.
warnings.warn
emits a Warning
, which may be printed to stderr
, ignored completely, or thrown like a normal Exception
(potentially crashing your application) depending upon the precise Warning
subclass emitted and how you've configured your Warnings Filter. By default, warnings will be printed to stderr
or ignored.
Warnings emitted by warnings.warn
are often useful to know about, but easy to miss (especially if you're running a Python program in a background process and not capturing stderr
). For that reason, it can be helpful to have them logged.
Python provides a built-in integration between the logging
module and the warnings
module to let you do this; just call logging.captureWarnings(True)
at the start of your script and all warnings emitted by the warnings
module will automatically be logged at level WARNING
.
Besides the canonical explanation in official documentation
warnings.warn() in library code if the issue is avoidable and the client application should be modified to eliminate the warning
logging.warning() if there is nothing the client application can do about the situation, but the event should still be noted
It is also worth noting that, by default warnings.warn("same message")
will show up only once. That is a major noticeable difference. Quoted from official doc
Repetitions of a particular warning for the same source location are typically suppressed.
>>> 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")
>>>