2013-01-22 14 views
152

Pracuję z kodem z wieloma rzutami (dla mnie w tej chwili) bezużytecznymi ostrzeżeniami przy użyciu biblioteki warnings. Czytanie (/ skanowanie) dokumentacji, którą znalazłem tylko w sposób, w jaki się znalazłem to disable warnings for single functions. Ale nie chcę zmieniać tak wiele kodu.Jak wyłączyć ostrzeżenia Pythona

Czy jest taka flaga jak python -no-warning foo.py?

Co byś polecił?

+4

Dlaczego chcesz wyłączyć ostrzeżenia? Czy ich poprawianie/rozwiązywanie nie byłoby lepsze w krótkim i długim okresie? Ostrzeżenia są zwykle zgłaszane z jakiegoś powodu, ignorowanie/wyciszanie ich prawdopodobnie doprowadziłoby do większych problemów w przyszłości. –

+5

Masz całkowitą rację, dałem ci +1 za komentarz, ale są, jak napisałem "w tej chwili" bezużyteczne dla mnie. – Framester

+5

@MartinSamson Ogólnie się zgadzam, ale istnieją uzasadnione przypadki ignorowania ostrzeżeń. Mam kilka z nich za pomocą prawidłowej składni Xpath w defusedxml: 'FutureWarning: To wyszukiwanie jest zepsute w wersji 1.3 i wcześniejszych i zostanie naprawione w przyszłej wersji. Jeśli polegasz na bieżącym zachowaniu, zmień go na [tę inną rzecz] '. Wolałbym teraz zignorować ostrzeżenia i poczekać, aż zostanie to w milczeniu naprawione, niż napisać niepotrzebnie brzydki kod, aby uniknąć nieszkodliwego ostrzeżenia. – Pedro

Odpowiedz

213

Czy patrzeć na odcinku suppress warnings z docs Pythona?

Jeśli używasz kodu, który znasz podniesie ostrzeżenie, takie jak nieaktualnych funkcji, ale nie chcę, aby zobaczyć ostrzeżenie, to jest możliwe, aby tłumić ostrzeżenie za pomocą menedżera kontekstowe catch_warnings:

import warnings 

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

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

nie toleruje go, ale może po prostu surpress wszystkie ostrzeżenia z tym:

import warnings 
warnings.filterwarnings("ignore") 

Ex:

>>> 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 
+0

Musisz więc owinąć kod w każdym pliku za pomocą 'with warnings.catch_warnings():'? – Framester

+7

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

+1

@Framester - Wymieniłem drugą opcję również 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

46

Można również zdefiniować zmienną środowiskową (nowa funkcja w 2010 roku - czyli pyton 2,7)

export PYTHONWARNINGS="ignore" 

testowy tak: Domyślnie

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

Ignoruj ​​ ostrzeżenia

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

"nowa funkcja w 2010 roku" FWIW oznacza, że ​​działa to dla wersji Python 2.7, ale nie dla wersji 2.6 lub starszych wersji 2.x. (Musiałem to sprawdzić, wciąż mam Python 2.6 w produkcji ...) –

+2

Dobrze. Dodano punkt Python 2.7 dodany –

+1

Jest to szczególnie przydatne do ignorowania ostrzeżeń podczas wykonywania testów. Używając 'tox', dodanie' PYTHONWARNINGS = ignore' do 'setenv' sprawia, że ​​wydruki są mniej brudne. –

2

ostrzeżenia są wyprowadzane przez stderr, a prostym rozwiązaniem jest dodanie "2>/dev/null" do interfejsu CLI. ma to wiele sensu dla wielu użytkowników, takich jak ci z centos 6, którzy utknęli w zależnościach Pythona 2.6 (jak mniam), a różne moduły są wypychane do granicy ekstynkcji w zasięgu.

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

ostrzeżenie jest nadal aktywne, ale wszystko, co chcesz, jest przeniesione z powrotem. ponowne przekierowanie stderr da ci czyste wyjście terminala/powłoki, chociaż zawartość standardowa sama się nie zmienia.

w odpowiedzi na FriendFX. zdanie pierwsze (1) odpowiada bezpośrednio na problem uniwersalnym rozwiązaniem. zdanie dwa (2) uwzględnia cytowaną kotwicę "wyłącz ostrzeżenia", która jest specyficzna dla Pythona 2.6 i zauważa, że ​​RHEL/centos 6 użytkowników nie może bezpośrednio zrobić bez wersji 2.6. mimo że nie podano żadnych konkretnych ostrzeżeń, para druga (2) odpowiada na pytanie 2.6, które najczęściej dostaję z powodu niedociągnięć w module kryptograficznym i jak można "zmodernizować" (tj. aktualizację, backport, naprawę) wydajność HTTPS/TLS Pythona . para trzecia (3) wyjaśnia jedynie rezultat zastosowania ponownego kierowania i aktualizacji modułu/zależności.

+2

Dzięki za poświęcenie czasu na odpowiedź. Zachowaj jednak ścisłe odpowiedzi na temat: Wspomniałeś o kilku rzeczach, które są nieistotne dla aktualnego pytania, 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 OP, zamiast tego wpisz komentarz pod pytaniem. – FriendFX

4

To stara sprawa, ale jest jakaś nowsza poradnictwo w PEP 565 że aby wyłączyć wszystkie ostrzeżenia jeśli piszesz aplikację Pythona należy użyć:

import sys 
import warnings 

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

Powodem tego jest to, że jest to zalecane domyślnie wyłącza wszystkie ostrzeżenia, ale w sposób znaczący umożliwia ich ponowne włączenie za pomocą linii poleceń lub python -W w linii poleceń lub PYTHONWARNINGS.

Powiązane problemy