Как отключить утверждения в Python?
То есть, если утверждение терпит неудачу, я не хочу, чтобы оно бросало AssertionError
, а чтобы оно продолжалось.
Как я могу это сделать?
Ответы:
Как отключить утверждения в Python?
Есть несколько подходов, которые влияют на один процесс, среду или одну строку кода.
Я демонстрирую каждый.
Использование -O
флага (заглавная O) отключает все утверждения утверждения в процессе.
Например:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Обратите внимание, что под отключением я подразумеваю, что он также не выполняет следующее за ним выражение:
$ python -Oc "assert 1/0"
$ python -c "assert 1/0"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Вы также можете использовать переменную среды, чтобы установить этот флаг.
Это повлияет на каждый процесс, который использует или наследует среду.
Например, в Windows установка, а затем очистка переменной среды:
C:\>python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
C:\>SET PYTHONOPTIMIZE=TRUE
C:\>python -c "assert False"
C:\>SET PYTHONOPTIMIZE=
C:\>python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
То же самое в Unix (с использованием set и unset для соответствующей функциональности)
Вы продолжаете свой вопрос:
если утверждение терпит неудачу, я не хочу, чтобы оно выдавало AssertionError, а чтобы оно продолжалось.
Если вы хотите, чтобы код не выполнялся, вы можете поймать либо гарантировать, что поток управления не достигает утверждения, например:
if False:
assert False, "we know this fails, but we don't get here"
или вы можете поймать ошибку утверждения:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
который печатает:
AssertionError('this code runs, fails, and the exception is caught')
и вы будете продолжать с того момента, как вы обработали AssertionError
.
Из в assert
документации :
Утверждение вроде этого:
assert expression #, optional_message
Эквивалентно
if __debug__:
if not expression: raise AssertionError #(optional_message)
А также,
встроенная переменная
__debug__
используетсяTrue
при обычных обстоятельствах,False
когда требуется оптимизация (опция командной строки-O
).
и далее
Назначение на
__debug__
незаконное. Значение встроенной переменной определяется при запуске интерпретатора.
Из документации по использованию:
Включите базовую оптимизацию. Это изменяет расширение имени файла для скомпилированных (байт-кода) файлов с .pyc на .pyo. См. Также PYTHONOPTIMIZE.
а также
Если для него задана непустая строка, это эквивалентно указанию
-O
параметра. Если установлено целое число, это эквивалентно указанию-O
нескольких раз.
if False: assert False
), либо вы можете поймать ошибку утверждения. Это ваш выбор. Обновлен ответ, чтобы ответить на ваш вопрос.
foo()
и коммутационные утверждения от: with skip_assertion(): foo()
. Преимущество этого в том, что мне не нужно добавлять еще один флаг в функцию
Assert
объекты Pass
объектами). Диспетчер контекста не будет работать напрямую для этого, но у вас может быть какой-то механизм, который таким образом использует оформленные функции. Тем не менее, я не рекомендую это. Я подозреваю, что причина вашего желания это сделать - вы вызываете код, который не контролируете, и получаете AssertionErrors. Если да, вероятно, вам нужно найти другое исправление.
Вызов Python с флагом -O:
test.py:
assert(False)
print 'Done'
Выход:
C:\temp\py>C:\Python26\python.exe test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
assert(False)
AssertionError
C:\temp\py>C:\Python26\python.exe -O test.py
Done
Оба из двух уже предоставленных ответов действительны (вызовите Python с помощью одного -O
или -OO
в командной строке).
Вот разница между ними:
-O
Включите базовую оптимизацию. Это изменяет расширение имени файла для скомпилированных (байт-кода) файлов с .pyc на .pyo.
-OO
Откажитесь от строк документации в дополнение к -O
оптимизации.
(Из документации Python )
Использование python -O
:
$ python -O
>>> assert False
>>>
Вы НЕ должны отключать (большинство) утверждений. Они ловят непредвиденные ошибки, когда внимание сосредоточено на другом. См. Правило 5 в «Степень десяти» .
Вместо этого защитите некоторые дорогостоящие проверки утверждений чем-то вроде:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Один из способов сохранить важные утверждения и позволить assert
оптимизировать операторы - это поднять их в операторе выбора:
if foo_is_broken():
raise AssertionError('Foo is broken!')
Запуск в оптимизированном режиме должен сделать это:
python -OO module.py
__debug__
значение "Ложь", но это запрещено.