Como desativar avisos de python


420

Estou trabalhando com código que lança muitos (para mim no momento) avisos inúteis usando a warningsbiblioteca. Ao ler (/ digitalizar) a documentação, encontrei apenas uma maneira de desativar avisos para funções únicas . Mas não quero mudar muito do código.

Existe talvez uma bandeira como python -no-warning foo.py?

O que você recomendaria?


9
@MartinSamson Eu geralmente concordo, mas há casos legítimos para ignorar avisos. Recebo vários destes de utilizar a sintaxe XPath válida em 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]. Prefiro ignorar os avisos agora e esperar que eles sejam corrigidos silenciosamente do que escrever códigos desnecessariamente feios apenas para evitar um aviso inofensivo.
Pedro

1
desativar avisos específicos: stackoverflow.com/questions/9134795/…
user3226167

Respostas:



576

Você olhou para a seção suprimir avisos dos documentos python?

Se você estiver usando o código que você sabe que irá gerar um aviso, como uma função preterida, mas não deseja vê-lo, será possível suprimi-lo usando o gerenciador de contexto catch_warnings:

import warnings

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

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

Eu não desculpo, mas você pode simplesmente suprimir todos os avisos com isso:

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

12
@Framester - sim, a IMO é a maneira mais limpa de suprimir avisos específicos; geralmente existem avisos porque algo pode estar errado; portanto, suprimir todos os avisos pela linha de comando pode não ser a melhor opção.
Mike

1
@Framester - listei a outra opção com um exemplo também ... Eu não gosto muito (por isso dei no comentário anterior), mas pelo menos agora você tem as ferramentas.
Mike

41
Se você espera apenas receber avisos de uma categoria específica, pode transmiti-lo usando o categoryargumento:warnings.filterwarnings("ignore", category=DeprecationWarning)
ostrokach

1
Isso é útil para mim nesse caso, porque html5lib lança avisos de lxml, mesmo que não esteja analisando xml. Graças
jamescampbell

5
Há também um parâmetro útil para a warnings.filterwarnings função: module. Ele permite que você ignore avisos do módulo especificado.
nome de usuário

104

Você também pode definir uma variável de ambiente (novo recurso em 2010 - ie python 2.7)

export PYTHONWARNINGS="ignore"

Teste como este: Padrão

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

Ignorar avisos

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

Para avisos de descontinuação , consulte como ignorar-avisos de descontinuação em python

Copiado aqui ...

Da documentação do warningsmódulo :

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

Se você estiver no Windows: passe -W ignore::DeprecationWarningcomo argumento para o Python. Melhor ainda resolver o problema, transmitindo para int .

(Observe que no Python 3.2, os avisos de descontinuação são ignorados por padrão.)

Ou:

import warnings

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

yourcode()

Agora você ainda recebe todos os outros DeprecationWarnings, mas não os causados ​​por:

import md5, sha

2
Isso é especialmente útil para ignorar avisos ao executar testes. Usar tox, adicionar PYTHONWARNINGS=ignorea setenvtorna a saída menos suja.
Kurt Bourbaki

2
Muito útil para a AWS CLI também.
Mckenzm 09/08/19

1
Mas isso não ignora o aviso de descontinuação. Posso perguntar como incluir esse?
Wey Shi #:


70

Esta é uma pergunta antiga, mas há algumas orientações mais recentes no PEP 565 que, para desativar todos os avisos, se você estiver escrevendo um aplicativo python, use:

import sys
import warnings

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

A razão pela qual isso é recomendado é que ele desativa todos os avisos por padrão, mas permite que eles sejam ativados novamente na python -Wlinha de comando ou PYTHONWARNINGS.


Isso é perfeito, pois não desabilitará todos os avisos em execução posterior
Orsiris de Jong

53

Se você não quer algo complicado, então:

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

10
E para voltar ao comportamento padrão:warnings.filterwarnings("default", category=FutureWarning)
Hans Bouwmeester

17

Se você souber quais são os avisos inúteis que costuma encontrar, poderá filtrá-los por mensagem.

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

Sei que isso é aplicável apenas a um nicho de situações, mas dentro de um numpycontexto, eu realmente gosto de usar np.errstate:

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

No entanto, usando np.errstate:

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

A melhor parte é que você pode aplicar isso apenas a linhas de código muito específicas.


-5

os avisos são enviados via stderr e a solução simples é anexar '2> / dev / null' à CLI. isso faz muito sentido para muitos usuários, como aqueles com centos 6 que estão presos às dependências do python 2.6 (como o yum) e vários módulos estão sendo levados ao limite da extinção em sua cobertura.

isso é especialmente verdadeiro para criptografia envolvendo SNI et cetera. é possível atualizar o 2.6 para manipulação de HTTPS usando o proc em: https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2

o aviso ainda está em vigor, mas tudo o que você deseja é portado. o redirecionamento do stderr deixará você com uma saída limpa de terminal / shell, embora o próprio conteúdo stdout não seja alterado.

respondendo ao FriendFX. a primeira frase responde diretamente ao problema com uma solução universal. a frase dois (2) leva em consideração a âncora citada re 'desativar avisos', que é específica do python 2.6 e observa que os usuários do RHEL / centos 6 não podem ficar diretamente sem o 2.6. embora nenhum aviso específico tenha sido citado, o parágrafo 2 (2) responde à pergunta 2.6 que eu mais frequentemente encontro sobre as falhas no módulo de criptografia e como alguém pode "modernizar" (ou seja, atualizar, backport, corrigir) o desempenho HTTPS / TLS do python . O parágrafo três (3) apenas explica o resultado do uso de redirecionar e atualizar o módulo / dependências.


4
Obrigado por reservar um tempo para responder. No entanto, mantenha as respostas estritamente no tópico: você menciona algumas coisas que são irrelevantes para a pergunta atual, como CentOS, Python 2.6, criptografia, urllib e back-port. Você pode editar sua pergunta para remover esses bits. Se você quiser saber mais detalhes do OP, deixe um comentário na pergunta.
precisa saber é
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.