Подтвердить что ты не робот

Дизайн python: почему утверждается утверждение, а не функция?

В Python assert - это инструкция, а не функция. Это было преднамеренное решение? Существуют ли какие-либо преимущества, заключающиеся в том, что assert является выражением (и зарезервированным словом) вместо функции?

Согласно docs, assert expression1, expression2 расширяется до

if __debug__:
    if not expression1: raise AssertionError(expression2)

В документах также говорится, что "текущий генератор кода не генерирует код для оператора assert при запросе оптимизации во время компиляции". Не зная подробностей, похоже, для того, чтобы это стало возможным, потребовался специальный случай. Но тогда особый случай можно было бы также использовать для оптимизации вызовов на assert().

Если assert была функцией, вы могли бы написать:

assert(some_long_condition,
       "explanation")

Но поскольку assert - это оператор, кортеж всегда вычисляет True и вы получаете

SyntaxWarning: assertion is always true, perhaps remove parentheses?

Правильный способ записи:

assert some_long_condition, \
       "explanation"

который, возможно, менее симпатичный.

4b9b3361

Ответ 1

Есть ли какие-либо преимущества для утверждения assert (и зарезервированного слова) вместо функции?

  • Невозможно переназначить функцию пользователя, что означает, что ее можно эффективно отключить во время компиляции, как указал @mgilson.
  • Оценка второго необязательного параметра отложена до тех пор, пока//если утверждение не сработает. Неловко сделать это с помощью функций и аргументов функции (нужно было бы пропустить лямбда.) Не откладывая оценку второго параметра, вы вводите дополнительные служебные данные.

Ответ 2

Одна из замечательных особенностей assert в python и на других языках (в частности, C) заключается в том, что вы можете удалить их для оптимизации кода, просто добавив правильный #define (необязательно в командной строке с любым компилятором я ' когда-либо использовались) или флаги оптимизации (-O в python). Если бы функция assert стала функцией, эту функцию невозможно было бы добавить в python, поскольку вы не знаете до ее выполнения, есть ли у вас встроенная функция assert или пользовательская функция с тем же именем.


Также обратите внимание, что в python вызовы функций достаточно дороги. Замена встроенного кода if __debug__: ..., вероятно, намного эффективнее, чем вызов функции, который может быть значительным, если вы поместите оператор assert в критическую для производительности процедуру.

Ответ 3

Я не эксперт в Python, но считаю, что производительность - одна из самых больших причин.

если у нас есть функция assert (выражение, объяснение) как функция, если выражение дорого оценивается, даже если мы находимся в режиме без отладки, Python должен оценить оба выражения, чтобы передать его функции assert.

Расширяя assert, выражение и объяснение фактически не оцениваются, если они действительно не нужны (когда отладка оценивается как true). Я считаю, что очень важно, если мы хотим, чтобы утверждение не влияло на производительность, когда это не было необходимо (т.е. Производительность не производилась в производственной системе).

Ответ 4

В дополнение к другим ответам (и вроде не по теме) отзыв. Чтобы избежать использования обратных косых черт, вы можете использовать неявное соединение линий внутри скобок.; -)

Вместо:

assert some_long_condition, \
       "explanation"

Вы можете написать:

assert some_long_condition, (
       "explanation")