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.