Jak wyłączyć ostrzeżenia w języku Python


420

Pracuję z kodem, który rzuca wiele (dla mnie w tej chwili) bezużytecznych ostrzeżeń za pomocą warningsbiblioteki. Czytanie (/ skanowanie) dokumentacji Znalazłem sposób na wyłączenie ostrzeżeń dla pojedynczych funkcji . Ale nie chcę zmieniać tak dużo kodu.

Czy może jest jak flaga python -no-warning foo.py?

Co byś polecił?


9
@MartinSamson Generalnie się zgadzam, ale istnieją uzasadnione przypadki ignorowania ostrzeżeń. Mam kilka z nich z pomocą ważnego składni XPath w defusedxml: FutureWarning: This search is broken in 1.3 and earlier, and will be fixed in a future version. If you rely on the current behaviour, change it to [this other thing]. Wolałbym teraz zignorować ostrzeżenia i poczekać na ich cichą naprawę niż napisać niepotrzebnie brzydki kod, aby uniknąć nieszkodliwego ostrzeżenia.
Pedro

1
wyłącz określone ostrzeżenia: stackoverflow.com/questions/9134795/…
user3226167

Odpowiedzi:



576

Czy spojrzałeś na sekcję ostrzeżeń o pomijaniu w dokumentach Pythona?

Jeśli używasz kodu, o którym wiesz, że wywoła ostrzeżenie, takiego jak przestarzała funkcja, ale nie chcesz widzieć ostrzeżenia, możesz je wyłączyć za pomocą menedżera kontekstu catch_warnings:

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    fxn()

Nie akceptuję tego, ale możesz po prostu ukryć wszystkie ostrzeżenia w ten sposób:

import warnings
warnings.filterwarnings("ignore")

Dawny:

>>> import warnings
>>> def f():
...  print('before')
...  warnings.warn('you are warned!')
...  print('after')
>>> f()
before
__main__:3: UserWarning: you are warned!
after
>>> warnings.filterwarnings("ignore")
>>> f()
before
after

12
@Framester - tak, IMO to najczystszy sposób na stłumienie określonych ostrzeżeń, ostrzeżenia są ogólnie, ponieważ coś może być nie tak, więc pomijanie wszystkich ostrzeżeń za pomocą wiersza poleceń może nie być najlepszym rozwiązaniem.
Mike

1
@Framester - wymieniłem też inną opcję z przykładem ... Nie podoba mi się to tak bardzo (z powodów, które podałem w poprzednim komentarzu), ale przynajmniej teraz masz narzędzia.
Mike

41
Jeśli spodziewasz się tylko, że złapiesz ostrzeżenia z określonej kategorii, możesz przekazać je za pomocą categoryargumentu:warnings.filterwarnings("ignore", category=DeprecationWarning)
ostrokach

1
Jest to dla mnie przydatne w tym przypadku, ponieważ html5lib wyrzuca ostrzeżenia lxml, nawet jeśli nie analizuje xml. Dzięki
jamescampbell

5
Jest też przydatnym parametrem dla warnings.filterwarnings funkcji: module. Pozwala zignorować ostrzeżenia z określonego modułu.
nazwa użytkownika

104

Możesz także zdefiniować zmienną środowiskową (nowa funkcja w 2010 r. - tj. Python 2.7)

export PYTHONWARNINGS="ignore"

Testuj tak: Domyślnie

$ export PYTHONWARNINGS="default"
$ python
>>> import warnings
>>> warnings.warn('my warning')
__main__:1: UserWarning: my warning
>>>

Zignoruj ostrzeżenia

$ export PYTHONWARNINGS="ignore"
$ python
>>> import warnings
>>> warnings.warn('my warning')
>>> 

Do zaniechania ostrzeżenia spojrzeć instrukcją ignorowania-deprecation-warnings-in-python

Skopiowano tutaj ...

Z dokumentacji warningsmodułu :

 #!/usr/bin/env python -W ignore::DeprecationWarning

Jeśli korzystasz z systemu Windows: przekaż -W ignore::DeprecationWarningjako argument do Pythona. Lepiej jednak rozwiązać problem, przesyłając na int .

(Uwaga: w Pythonie 3.2 ostrzeżenia o wycofaniu są domyślnie ignorowane).

Lub:

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings("ignore", category=DeprecationWarning)
    import md5, sha

yourcode()

Teraz nadal masz wszystkie inne DeprecationWarning, ale nie te spowodowane przez:

import md5, sha

2
Jest to szczególnie przydatne do ignorowania ostrzeżeń podczas wykonywania testów. Używanie tox, dodawanie PYTHONWARNINGS=ignoredo setenvsprawia, że ​​wyjście jest mniej brudne.
Kurt Bourbaki,

2
Bardzo przydatne również dla interfejsu AWS CLI.
mckenzm

1
Ale to nie ignoruje ostrzeżenia o rezygnacji. Czy mogę zapytać, jak to uwzględnić?
Wey Shi,


70

To stare pytanie, ale w PEP 565 jest kilka nowszych wskazówek, że aby wyłączyć wszystkie ostrzeżenia, jeśli piszesz aplikację python, powinieneś użyć:

import sys
import warnings

if not sys.warnoptions:
    warnings.simplefilter("ignore")

Jest to zalecane dlatego, że domyślnie wyłącza wszystkie ostrzeżenia, ale pozwala na ich ponowne włączenie za pośrednictwem python -Wwiersza poleceń lub PYTHONWARNINGS.


Jest to idealne, ponieważ nie wyłączy wszystkich ostrzeżeń w późniejszym wykonaniu
Orsiris de Jong

52

Jeśli nie chcesz czegoś skomplikowanego, to:

import warnings
warnings.filterwarnings("ignore", category=FutureWarning)

10
Aby przywrócić domyślne zachowanie:warnings.filterwarnings("default", category=FutureWarning)
Hans Bouwmeester

17

Jeśli wiesz, jakie są zwykle bezużyteczne ostrzeżenia, możesz je filtrować według wiadomości.

import warnings

#ignore by message
warnings.filterwarnings("ignore", message="divide by zero encountered in divide")

#part of the message is also okay
warnings.filterwarnings("ignore", message="divide by zero encountered") 
warnings.filterwarnings("ignore", message="invalid value encountered")

0

Zdaję sobie sprawę, że ma to zastosowanie tylko do niszy sytuacji, ale w numpykontekście bardzo lubię używać np.errstate:

np.sqrt(-1)
__main__:1: RuntimeWarning: invalid value encountered in sqrt
nan

Jednak używając np.errstate:

with np.errstate(invalid='ignore'):
    np.sqrt(-1)
nan

Najlepsze jest to, że możesz zastosować to tylko do bardzo określonych wierszy kodu.


-5

ostrzeżenia są wysyłane przez stderr, a prostym rozwiązaniem jest dołączenie „2> / dev / null” do CLI. ma to sens dla wielu użytkowników, takich jak centos 6, którzy utknęli w zależnościach Pythona 2.6 (takich jak yum), a różne moduły są wypychane na skraj wyginięcia w swoim zasięgu.

jest to szczególnie prawdziwe w przypadku kryptografii obejmującej SNI i cetera. można zaktualizować 2.6 do obsługi HTTPS za pomocą proc na: https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2

ostrzeżenie jest nadal na miejscu, ale wszystko, co chcesz, jest przeniesione z powrotem. re-direct z stderr pozostawi ci czyste wyjście terminala / powłoki, chociaż sama zawartość standardowego wyjścia się nie zmienia.

odpowiadanie na FriendFX. zdanie pierwsze (1) odpowiada bezpośrednio na problem uniwersalnym rozwiązaniem. zdanie drugie (2) bierze pod uwagę cytowaną kotwicę „wyłącz ostrzeżenia”, która jest specyficzna dla Pythona 2.6, i zauważa, że ​​użytkownicy RHEL / centos 6 nie mogą bezpośrednio obejść się bez 2.6. chociaż nie podano żadnych konkretnych ostrzeżeń, para druga (2) odpowiada na pytanie 2.6, które najczęściej dostaję niedociągnięcia w module kryptograficznym i jak można „zmodernizować” (tj. uaktualnić, backport, naprawić) wydajność HTTPS / TLS Pythona . paragraf trzeci (3) wyjaśnia jedynie rezultat zastosowania przekierowania i aktualizacji modułu / zależności.


4
Dzięki za poświęcenie czasu na odpowiedź. Zachowaj jednak odpowiedzi ściśle na temat: Podajesz kilka rzeczy, które są nieistotne dla pytania w obecnej formie, takie jak CentOS, Python 2.6, kryptografia, urllib, back-porting. Możesz edytować swoje pytanie, aby usunąć te bity. Jeśli chcesz poznać więcej szczegółów z PO, zostaw komentarz pod pytaniem.
FriendFX
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.