Як вимкнути твердження в 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 (використання набору та зняття для відповідної функціональності)
Ви продовжуєте своє запитання:
якщо твердження не вдається, я не хочу, щоб воно викидало 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 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!')
__debug__
значення False, але це заборонено.