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

82

Jaka jest różnica między nimi warnings.warn()i logging.warn()pod względem tego, co robią i jak należy ich używać?

hekevintran
źródło
8
czy rozważyłbyś zmianę zaakceptowanej odpowiedzi tutaj?
Antti Haapala

Odpowiedzi:

-5

Jeden z nich wywołuje wyjątek, który można przechwycić lub zignorować w razie potrzeby, a drugi opcjonalnie dodaje wpis do dziennika na podstawie bieżącego poziomu rejestrowania. Jeden powinien być używany, gdy jeden ostrzega o różnych rzeczach w kodzie, a drugi powinien być używany podczas logowania.

Ignacio Vazquez-Abrams
źródło
23
O ile rozumiem, przyjęta odpowiedź jest błędna. Ani ostrzeżenia, ani rejestrowanie nie stanowią wyjątku. Ale drukuj wiadomości. Mają jednak inną systematyczność (jest jednak możliwe zintegrowanie ostrzeżeń z logowaniem przez logging.captureWarnings()). Wiadomości ostrzegawcze są domyślnie wyświetlane tylko raz, jak wyjaśnił @cxrodgers, aby poinformować użytkownika, aby zmienił swój kod. Logując się na innych i dokumentując wszystkie ostrzeżenia, można jednak skonfigurować, co ma być wyświetlane szczegółowo. Ostrzeżenia można zgłaszać do wyjątków za pomocą opcji `-W błąd '.
DerWeh
Przykro mi to mówić, ta odpowiedź nie jest zbyt pomocna. „podnosi się…” i „należy…”? Który jest który? warningsczy logging?
Peter Lillevold
86

Zgadzam się z drugą odpowiedzią - loggingsłuży do logowania i warningjest ostrzeżeniem - ale chciałbym dodać więcej szczegółów.

Oto HOWTO w stylu samouczka, przeprowadzające Cię przez kolejne etapy korzystania z loggingmodułu. https://docs.python.org/3/howto/logging.html

To bezpośrednio odpowiada na twoje pytanie:

warnings.warn () w kodzie biblioteki, jeśli problemu można uniknąć, a aplikację kliencką należy zmodyfikować w celu wyeliminowania ostrzeżenia

logging.warning (), jeśli aplikacja kliencka nie może nic zrobić w tej sytuacji, ale nadal należy odnotować zdarzenie

cxrodgers
źródło
60

logging.warningpo prostu rejestruje coś na WARNINGpoziomie, w taki sam sposób, jak logging.infologuje na INFOpoziomie i logging.errorrejestruje na ERRORpoziomie. Nie ma specjalnego zachowania.

warnings.warnemituje a Warning, który może zostać wydrukowany stderr, całkowicie zignorowany lub wyrzucony jak normalny Exception(potencjalnie powodujący awarię aplikacji) w zależności od dokładnej Warningwyemitowanej podklasy i sposobu skonfigurowania filtru ostrzeżeń . Domyślnie ostrzeżenia będą drukowane stderrlub ignorowane.

Ostrzeżenia emitowane przez program warnings.warnsą często przydatne, ale łatwo je przeoczyć (zwłaszcza jeśli uruchamiasz program w Pythonie w tle i nie przechwytujesz stderr). Z tego powodu ich zalogowanie może być pomocne.

Python zapewnia wbudowaną integrację między loggingmodułem a warningsmodułem, aby umożliwić ci to; wystarczy wywołać logging.captureWarnings(True)na początku skryptu, a wszystkie ostrzeżenia wysyłane przez warningsmoduł będą automatycznie rejestrowane na poziomie WARNING.

Mark Amery
źródło
27

Oprócz wyjaśnienia kanonicznego w oficjalnej dokumentacji

warnings.warn () w kodzie biblioteki, jeśli problemu można uniknąć, a aplikację kliencką należy zmodyfikować w celu wyeliminowania ostrzeżenia

logging.warning (), jeśli aplikacja kliencka nie może nic zrobić w tej sytuacji, ale nadal należy odnotować zdarzenie

Warto też zaznaczyć, że domyślnie warnings.warn("same message")pojawi się tylko raz. To główna zauważalna różnica. Cytat z oficjalnego doc

Powtórzenia konkretnego ostrzeżenia dla tej samej lokalizacji źródłowej są zwykle pomijane.

>>> 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
źródło
1
Zwróć uwagę, że „pokaż tylko raz” jest zamierzonym domyślnym zachowaniem, ale filtry ostrzegawcze mogą to zmienić.
gerrit