Разница между попыткой рейза и утверждением

Я учусь Python на некоторое время и raise функции и assert это (то, что я понял, что оба они сбою приложения, в отличие от попытки - за исключением) действительно похожи, и я не могу видеть ситуацию, в которой вы будете использовать raise или assert, над try

Итак, в чем разница между Raise, Try и Assert?

Ответ 1

Утверждение:

Используется, когда вы хотите "остановить" script на основе определенного условия и вернуть что-то, чтобы ускорить отладку:

list_ = ["a","b","x"]
assert "x" in list_, "x is not in the list"
print("passed") 
#>> prints passed

list_ = ["a","b","c"]
assert "x" in list_, "x is not in the list"
print("passed")
#>> 
Traceback (most recent call last):
  File "python", line 2, in <module>
AssertionError: x is not in the list

Raise:

Для этого полезны две причины:

1/Используется с параметрами try и except. Поднимите ошибку по вашему выбору, можно настроить как ниже и не останавливать script, если вы pass или contiune script; или могут быть предопределены ошибки raise ValueError()

class Custom_error(BaseException):
    pass

try:
    print("hello")
    raise Custom_error
    print("world")
except Custom_error:
    print("found it not stopping now")

print("im outside")

>> hello
>> found it not stopping now
>> im outside

Заметил, что это не остановилось? Мы можем остановить его, используя только выход (1) в исключающем блоке.

2/Raise также может использоваться для повторной обработки текущей ошибки, чтобы передать ее стек, чтобы увидеть, может ли что-то еще справиться с ней.

except SomeError, e:
     if not can_handle(e):
          raise
     someone_take_care_of_it(e)

Попробовать/исключить блоки:

делает именно то, что вы думаете, что-то пытается, если возникает ошибка, вы ее поймаете и справляетесь с ней, как вам нравится. Нет примера, так как там выше.

Ответ 2

assert cond, "text"

расширяется до значения

if cond == False:
  raise AssertionError("text")

используйте assert, потому что это более читаемо.

Ответ 3

raise - создать исключение.

assert - создать исключение , если данное условие (или не соответствует) истинно.

try - выполнить код, который может вызвать исключение, и если да, поймите его.

Ответ 4

Блоки

try/except позволяют вам улавливать и управлять исключениями. Исключения могут быть вызваны raise, assert и большим количеством ошибок, таких как попытка индексации пустого списка. raise обычно используется, когда вы обнаружили условие ошибки. assert аналогичен, но исключение возникает только в случае выполнения условия.

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

Утверждения, как правило, зарезервированы для случаев "я клянусь, что этого не может быть", которые, похоже, все равно происходят. Это больше похоже на отладку времени выполнения, чем обычное обнаружение ошибок во время выполнения. Утверждения могут быть отключены, если вы используете флаг -O или запускаете из .pyo файлов вместо файлов .pyc, поэтому они не должны быть частью регулярного обнаружения ошибок.

Если код качества продукции вызывает исключение, тогда выясните, что вы сделали неправильно. Если он вызывает AssertionError, у вас есть большая проблема.

Ответ 5

Исключения - это то, что используют Python (и некоторые другие языки) для устранения ошибок, возникающих при выполнении кода. raise ExceptionName говорит, что в коде есть ошибка, и указывает, в чем проблема, путем создания исключения, связанного с этой проблемой. assert expression оцените expression и вызывает исключение, если оно ложно.

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

Пример: скажем, что у вас есть словарь и список. Вы хотите искать вещи из списка в словаре, пока не достигнете того, что не находится в словаре:

try:
    for item in my_list:
        print(my_dictionary[item])
except KeyError as e: #KeyError is the Exception raised when a key is not in a dictionary
    print('There is no {} in the dictionary'.format(e.args[0]))

Ответ 6

Утверждение обычно используется при тестировании кода, чтобы убедиться, что что-то сработало:

def test_bool():
    assert True != False

Где в качестве try, поднимать и исключая обработку исключений makeup, которая является предпочтительным способом в python для обработки и распространения ошибок.

Большинство библиотек и встроенных модулей python будут повышаться и исключение одного типа или другого, если что-то пойдет не так. Часто в вашем собственном коде вы также хотите создать исключение, если обнаружите, что что-то не так. Скажем, в качестве примера вы пишете валидатор адресов электронной почты, и вы хотели создать исключение, если адрес не содержал знак @. у вас может быть что-то вроде этого (это код игрушки, на самом деле не проверяйте такие сообщения электронной почты):

def validate_email(address):
    if not "@" in address:
        raise ValueError("Email Addresses must contain @ sign")

Затем в другом месте вашего кода вы можете вызвать функцию validate_email, и если он завершится, исключение будет выбрано.

try:
    validate_email("Mynameisjoe.com")
except ValueError as ex:
    print("We can do some special invalid input handling here, Like ask the user to retry the input")
finally:
    close_my_connection()
    print("Finally always runs whether we succeed or not. Good for clean up like shutting things down.")

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

Одна вещь, которую вы не хотите делать, это что-то вроде:

if __name__ == '__main__':
    try:
        print(1/0)
    except Exception as ex:
        pass

Теперь у вас нет способа узнать, почему ваше приложение взорвалось.

Одна вещь, которую вы часто увидите, и это нормально:

import logging
if __name__ == '__main__':
    try:
        print(1/0)
    except Exception as ex:
        logging.exception(ex)
        raise

Поднятие в этом случае, поскольку у него нет параметров, повторно вызывает ту же ошибку. Часто в веб-коде вы увидите нечто похожее, которое не восстанавливает исключение, потому что оно отправит клиенту 500 ошибку и затем продолжит следующий запрос, поэтому в этом случае вы не хотите, чтобы программа закончилась.

Ответ 7

Утверждения

  • Следует использовать только в целях отладки
  • Хотя они похожи на Повышение/Исключения, они служат различным целям, потому что они полезны для указания сценариев, в которых программная ошибка не может быть исправлена из
  • Утверждения всегда вызывают исключения AssertionError, вот как они работают:

синтаксис: assert_stmt ::= "assert" expression1 ["," expression2]

во время исполнения это переводится как:

if __debug__:
  if not expression1:
    raise AssertionError(expression2)
  • __debug__ - это встроенный флаг, который обычно имеет значение true, но если оптимизация запущена, он будет ложным, поэтому утверждения будут иметь мертвый код => отключены с флагами -O и -O O при запуске Python (или переменной env PYTHONOPTIMIZE) в CPython), поэтому не полагайтесь на них для логики кода.
  • Не используйте утверждения для проверки данных из-за предыдущего пункта
  • Хороший вариант использования для утверждений => заставляет программу "взорваться", если какое-то неожиданное состояние программы должно остановить ее при любых обстоятельствах => таким образом, при обстоятельствах, когда исключение, если оно было обнаружено, приведет к завершению программы вообще.
  • Если у вас есть программа без ошибок, то утверждения никогда не должны запускаться, они служат проверкой работоспособности программы
  • Будьте осторожны при использовании структур данных (таких как кортежи) в качестве выражения1 в утверждениях, которые всегда оцениваются как True для непустых значений =>, утверждения всегда будут срабатывать, ломая программу - например: assert (<some_test>, 'warn string') => обратите внимание на конструкцию кортежа (неправильно!)

Проверить: Ловля поддельных Python утверждает на CI Дэна Бадера

Поднять/Исключения

  • Их целью является обработка сценариев, когда программная логика находится в исключительном состоянии, но вы знаете, какую логику восстанавливать из этого состояния
  • Когда вы вызываете исключение, вы можете сделать тип исключения соответствующим ошибке (лучше контролировать семантическое значение) и перехватить его позже =>, чтобы вы могли создать несколько типов исключений, которые вы знаете, как восстанавливать, и обрабатывать их
  • Они представляют собой механизм обработки известных/ожидаемых сценариев ошибок времени выполнения.
  • Полезно для проверки данных при использовании операторов if и повышении исключений для проверки для каждого сценария

Пытаться

  • Это всего лишь синтаксический элемент обработки исключений при кодировании

Кстати, я очень рекомендую книгу Дэна Бадера "Python Tricks: The Book" (из realpython.com)

Ответ 8

Нет разницы между assert и raise AssertionError, они будут скомпилированы с одинаковым байт-кодом:

import dis

def foo1(param):
    assert param, "fail"

def foo2(param):
    if not param:
        raise AssertionError("fail")

print(dis.dis(foo1))
print(dis.dis(foo2))

Output:

 4           0 LOAD_FAST                0 (param)
             2 POP_JUMP_IF_TRUE        12
             4 LOAD_GLOBAL              0 (AssertionError)
             6 LOAD_CONST               1 ('fail')
             8 CALL_FUNCTION            1
            10 RAISE_VARARGS            1
       >>   12 LOAD_CONST               0 (None)
            14 RETURN_VALUE
None
 7           0 LOAD_FAST                0 (param)
             2 POP_JUMP_IF_TRUE        12

 8           4 LOAD_GLOBAL              0 (AssertionError)
             6 LOAD_CONST               1 ('fail')
             8 CALL_FUNCTION            1
            10 RAISE_VARARGS            1
       >>   12 LOAD_CONST               0 (None)
            14 RETURN_VALUE
None