Отключить утверждения в Python
-
13-09-2019 - |
Вопрос
Как мне отключить утверждения в Python?
То есть, если утверждение завершается неудачей, я не хочу, чтобы оно выдавало AssertionError
, но продолжать идти.
Как мне это сделать?
Решение
Как мне отключить утверждения в Python?
Существует несколько подходов, которые влияют на один процесс, среду или одну строку кода.
Я демонстрирую каждый из них.
Для всего процесса
Используя -O
флаг (заглавная буква O) отключает все инструкции assert в процессе.
Например:
$ 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 и сбросить настройки для соответствующей функциональности)
Единственная точка в коде
Вы продолжаете свой вопрос:
если утверждение завершается неудачей, я не хочу, чтобы оно выдавало 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
несколько раз.
Другие советы
Вызовите 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 -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