Python: сделать предупреждение во время выполнения ошибкой вместо [duplicate]

Стандартное решение для сортировки OrderBy, как показано в Как я могу заказать List & lt; string & gt;? , должен работать в этом случае, вы просите его заказать по Version:

 var listOfStrings = new List{"1.2", "2.3", "0.1"};
 listOfStrings = listOfStrings.OrderBy(x => new Version(x)).ToList();

113
задан ali_m 13 November 2015 в 22:03
поделиться

4 ответа

Кажется, что ваша конфигурация использует опцию print для numpy.seterr :

>>> import numpy as np
>>> np.array([1])/0   #'warn' mode
__main__:1: RuntimeWarning: divide by zero encountered in divide
array([0])
>>> np.seterr(all='print')
{'over': 'warn', 'divide': 'warn', 'invalid': 'warn', 'under': 'ignore'}
>>> np.array([1])/0   #'print' mode
Warning: divide by zero encountered in divide
array([0])

Это означает, что предупреждение, которое вы видите, не является реальным предупреждением, но это всего лишь некоторые символы, напечатанные на stdout (см. документацию для seterr ). Если вы хотите его поймать, вы можете:

  1. Использовать numpy.seterr(all='raise'), который будет напрямую возбуждать исключение. Это, однако, изменяет поведение всех операций, поэтому это довольно большое изменение в поведении.
  2. Используйте numpy.seterr(all='warn'), который преобразует печатное предупреждение в реальное предупреждение, и вы сможете использовать выше, чтобы локализовать это изменение в поведении.

Как только у вас есть предупреждение, вы можете использовать модуль warnings для управления обработкой предупреждений:

>>> import warnings
>>> 
>>> warnings.filterwarnings('error')
>>> 
>>> try:
...     warnings.warn(Warning())
... except Warning:
...     print 'Warning was raised as an exception!'
... 
Warning was raised as an exception!

Внимательно прочитайте документацию для filterwarnings , поскольку она позволяет фильтровать только предупреждение, которое вы хотите, и имеет другие параметры. Я также хотел бы рассмотреть catch_warnings , который является менеджером контекста, который автоматически сбрасывает исходную функцию filterwarnings:

>>> import warnings
>>> with warnings.catch_warnings():
...     warnings.filterwarnings('error')
...     try:
...         warnings.warn(Warning())
...     except Warning: print 'Raised!'
... 
Raised!
>>> try:
...     warnings.warn(Warning())
... except Warning: print 'Not raised!'
... 
__main__:2: Warning: 
137
ответ дан Bakuriu 19 August 2018 в 03:59
поделиться
  • 1
    Я думаю, что это начало. Но на самом деле это не проблема. Если я добавлю warnings.warn (Warning ()) в свой код в блоке try, он поймает предупреждение. По какой-то причине он не улавливает разницу с нулевым предупреждением. Вот точное предупреждение: Предупреждение: деление на ноль встречается в int_scalars – John K. 10 April 2013 в 20:00
  • 2
    @JohnK. Вы должны отредактировать свой вопрос и добавить точный результат, иначе мы не можем сказать, что не так. Возможно, может , чтобы numpy определял этот класс предупреждения где-то, и вам нужно обнаружить, в каком субпакете можно его поймать. Неважно, я обнаружил, что вы должны использовать RuntimeWarning. Обновлен ответ. – Bakuriu 10 April 2013 в 20:01
  • 3
    Ты уверен? Я изменил свой код на использование, кроме RuntimeWarning :. Он все еще не работает = / – John K. 10 April 2013 в 20:06
  • 4
    @JohnK. В документации указывается, что RuntimeWarning поднят. Проблема может заключаться в том, что ваша конфигурация numpy использует параметр print, который просто печатает предупреждение, но это не является реальным предупреждением, обрабатываемым модулем warnings ... Если это так, вы можете попытаться использовать numpy.seterr(all='warn') и попробуй еще раз. – Bakuriu 10 April 2013 в 20:08
  • 5
    В моей версии numpy вы не можете использовать numpy.seterr(all='error'), error должно быть raise. – detly 14 May 2014 в 03:32

Чтобы добавить немного к ответу @ Bakuriu:

Если вы уже знаете, где может возникнуть предупреждение, часто бывает полезно использовать контекстный менеджер numpy.errstate а не numpy.seterr , который обрабатывает все последующие предупреждения одного и того же типа независимо от того, где они происходят в вашем коде:

import numpy as np

a = np.r_[0]
with np.errstate(divide='raise'):
    try:
        a / 0   # this gets caught and handled as an exception
    except FloatingPointError:
        print('oh no!')
a / 0           # this prints a RuntimeWarning as usual 
24
ответ дан ali_m 19 August 2018 в 03:59
поделиться
  • 1
    Примечательно, что он поднимает FloatingPointError, а не ZeroDivisionError. – gerrit 6 December 2016 в 16:32

Чтобы подробно остановиться на ответе @ Bakuriu выше, я обнаружил, что это позволяет мне поймать предупреждение во время выполнения так же, как я поймаю предупреждение об ошибке, распечатав предупреждение красиво:

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings('error')
    try:
        answer = 1 / 0
    except Warning as e:
        print('error found:', e)

Вы, вероятно, сможете поиграть с размещением места warnings.catch_warnings () в зависимости от того, насколько большой размер зонтика, который вы хотите использовать, с такими ловушками.

18
ответ дан Nathan Musoke 19 August 2018 в 03:59
поделиться

Удалить предупреждения.filterwarnings и добавить:

numpy.seterr(all='raise')
2
ответ дан ShitalShah 19 August 2018 в 03:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: