Ручное повышение (выброс) исключения в Python

Как я могу создать исключение в Python, чтобы впоследствии его можно было поймать за except блока?

  • socket.error: Адрес уже используется
  • pandas: итерация по индексу DataFrame с loc
  • Могу ли я использовать псевдоним для выполнения программы из сценария python
  • Разбор большого (9GB) файлов с использованием python
  • Запросы с несколькими соединениями
  • Как обрабатывать IncompleteRead: в python
  • Графический график 3D-графика Matplotlib с градиентом цвета
  • Уроки Python и unicode
  • 5 Solutions collect form web for “Ручное повышение (выброс) исключения в Python”

    Как вручную выставить / создать исключение в Python?

    Используйте наиболее специфичный конструктор исключений, который семантически соответствует вашей проблеме .

    Будьте конкретны в своем сообщении, например:

     raise ValueError('A very specific bad thing happened') 

    Не поднимайте общие исключения:

    Избегайте создания общего исключения, чтобы поймать его, вам придется поймать все другие более конкретные исключения, которые подклассифицируют его.

    Проблема 1: Скрытие ошибок

     raise Exception('I know Python!') # don't, if you catch, likely to hide bugs. 

    Например:

     def demo_bad_catch(): try: raise ValueError('represents a hidden bug, do not catch this') raise Exception('This is the exception you expect to handle') except Exception as error: print('caught this error: ' + repr(error)) >>> demo_bad_catch() caught this error: ValueError('represents a hidden bug, do not catch this',) 

    Проблема 2: Не поймать

    и более конкретные уловы не пойдут на общее исключение:

     def demo_no_catch(): try: raise Exception('general exceptions not caught by specific handling') except ValueError as e: print('we will not catch e') >>> demo_no_catch() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in demo_no_catch Exception: general exceptions not caught by specific handling 

    Лучшая практика:

    raise заявление

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

     raise ValueError('A very specific bad thing happened') 

    который также удобно позволяет произвольному количеству аргументов передаваться конструктору. Это работает на Python 2 и 3.

     raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz') 

    К этим аргументам относится атрибут args объекта Exception. Например:

     try: some_code_that_may_raise_our_value_error() except ValueError as err: print(err.args) 

    печать

     ('message', 'foo', 'bar', 'baz') 

    В Python 2.5 в BaseException был добавлен фактический атрибут message в пользу поощрения пользователей к подклассам «Исключения» и прекращению использования args , но введение message и первоначальное устаревание аргументов было отменено .

    except

    Когда внутри предложения except вы можете захотеть, например, зарегистрировать, что произошел определенный тип ошибки, а затем ререйз. Лучший способ сделать это при сохранении трассировки стека – использовать голый оператор raise, например:

     logger = logging.getLogger(__name__) try: do_something_in_app_that_breaks_easily() except AppError as error: logger.error(error) raise # just this! # raise AppError # Don't do this, you'll lose the stack trace! 

    Не изменяйте свои ошибки … но если вы настаиваете.

    Вы можете сохранить stacktrace (и значение ошибки) с помощью sys.exc_info() , но это больше подвержено ошибкам и имеет проблемы совместимости между Python 2 и 3 , предпочитают использовать голый raise для ререйза.

    Объяснить – sys.exc_info() возвращает тип, значение и трассировку.

     type, value, traceback = sys.exc_info() 

    Это синтаксис в Python 2 – обратите внимание, что это несовместимо с Python 3:

      raise AppError, error, sys.exc_info()[2] # avoid this. # Equivalently, as error *is* the second object: raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] 

    Если вы хотите, вы можете изменить то, что происходит с вашим новым рейзом – например, установить новые аргументы для экземпляра:

     def error(): raise ValueError('oops!') def catch_error_modify_message(): try: error() except ValueError: error_type, error_instance, traceback = sys.exc_info() error_instance.args = (error_instance.args[0] + ' <modification>',) raise error_type, error_instance, traceback 

    И мы сохранили весь трассировку при изменении аргументов. Обратите внимание, что это не лучшая практика, и это недействительный синтаксис в Python 3 (что затрудняет работу с совместимостью).

     >>> catch_error_modify_message() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in catch_error_modify_message File "<stdin>", line 2, in error ValueError: oops! <modification> 

    В Python 3 :

      raise error.with_traceback(sys.exc_info()[2]) 

    Опять же: избегайте ручного управления трассировками. Он менее эффективен и подвержен ошибкам. И если вы используете threading и sys.exc_info вы даже можете получить неверную трассировку (особенно если вы используете обработку исключений для потока управления, что я лично стараюсь избегать).

    Python 3, цепочка исключений

    В Python 3 вы можете связать Исключения, которые сохраняют трассировку:

      raise RuntimeError('specific message') from error 

    Помните:

    • это позволяет изменить тип ошибки, и
    • это несовместимо с Python 2.

    Устаревшие методы:

    Они могут легко скрыть и даже попасть в производственный код. Вы хотите поднять исключение / ошибку, и их выполнение приведет к возникновению ошибки, но не к намеченной!

    Действителен в Python 2, но не в Python 3, является следующим:

     raise ValueError, 'message' # Don't do this, it's deprecated! 

    Действует только в более старых версиях Python (2.4 и ниже), вы все равно можете видеть, как люди поднимают строки:

     raise 'message' # really really wrong. don't do this. 

    Во всех современных версиях это фактически вызовет TypeError, потому что вы не поднимаете тип BaseException. Если вы не проверяете правильное исключение и не имеете рецензента, который знает об этой проблеме, он может попасть в производство.

    Пример использования:

    Я поднимаю Исключения, чтобы предупреждать потребителей моего API, если они используют его неправильно:

     def api_func(foo): '''foo should be either 'baz' or 'bar'. returns something very useful.''' if foo not in _ALLOWED_ARGS: raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo))) 

    Создайте свои собственные типы ошибок, когда:

    «Я хочу сделать ошибку специально, чтобы она попала в исключение»,

    Вы можете создавать свои собственные типы ошибок, если вы хотите указать что-то конкретное в своем приложении, просто подклассифицируйте соответствующую точку в иерархии исключений:

     class MyAppLookupError(LookupError): '''raise this when there's a lookup error for my app''' 

    и использование:

     if important_key not in resource_dict and not ok_to_be_missing: raise MyAppLookupError('resource is missing, and that is not ok.') 

    НЕ ДЕЛАЙТЕ ЭТО . Принятие голого Exception абсолютно не подходит; см . отличный ответ Аарона Холла .

    Не может быть намного более питоническим, чем это:

     raise Exception("I know python!") 

    Если вы хотите получить дополнительную информацию, см. Документы для подписи для python.

    Для обычного случая, когда вам нужно выкинуть исключение в ответ на некоторые неожиданные условия и что вы никогда не намереваетесь поймать, а просто быстро выйти из строя, чтобы вы могли отлаживать оттуда, если это когда-либо случится – наиболее логичным кажется AssertionError :

     if 0 < distance <= RADIUS: #Do something. elif RADIUS < distance: #Do something. else: raise AssertionError("Unexpected value of 'distance'!", distance) 

    В Python3 существует 4 разных синтаксиса для исключения исключений:

     1. raise exception 2. raise exception (args) 3. raise 4. raise exception (args) from original_exception 

    1. Повысить исключение против 2. Повысить исключение (args)

    Если вы используете raise exception (args) для создания исключения, тогда args будут напечатаны при печати объекта исключения – как показано в примере ниже.

      #raise exception (args) try: raise ValueError("I have raised an Exception") except ValueError as exp: print ("Error", exp) # Output -> Error I have raised an Exception #raise execption try: raise ValueError except ValueError as exp: print ("Error", exp) # Output -> Error 

    3.raise

    raise без аргументов повторно вызывает последнее исключение. Это полезно, если вам нужно выполнить некоторые действия после того, как вы поймаете это исключение, а затем хотите повторно поднять его. Но если раньше не было исключений, оператор raise вызывает TypeError Exception.

     def somefunction(): print("some cleaning") a=10 b=0 result=None try: result=a/b print(result) except Exception: #Output -> somefunction() #some cleaning raise #Traceback (most recent call last): #File "python", line 8, in <module> #ZeroDivisionError: division by zero 

    4. Повысить исключение (args) от original_exception

    Этот оператор используется для создания цепочки исключений, в котором исключение, возникающее в ответ на другое исключение, может содержать сведения об исходном исключении – как показано в примере ниже.

     class MyCustomException(Exception): pass a=10 b=0 reuslt=None try: try: result=a/b except ZeroDivisionError as exp: print("ZeroDivisionError -- ",exp) raise MyCustomException("Zero Division ") from exp except MyCustomException as exp: print("MyException",exp) print(exp.__cause__) 

    Вывод:

     ZeroDivisionError -- division by zero MyException Zero Division division by zero 

    Сначала прочтите существующие ответы, это просто добавление.

    Обратите внимание, что вы можете создавать исключения с аргументами или без них.

    Пример:

     raise SystemExit 

    выходит из программы, но вы, возможно, захотите узнать, что произошло. Таким образом, вы можете использовать это.

     raise SystemExit("program exited") 

    это приведет к тому, что перед закрытием программы будет выведена «программа вышла».

    Python - лучший язык программирования в мире.