web-dev-qa-db-fra.com

Désactiver les assertions dans Python

Comment désactiver les assertions en Python?

Autrement dit, si une assertion échoue, je ne veux pas qu'elle lance un AssertionError, mais continue.

Comment je fais ça?

81
Claudiu

Comment désactiver les assertions en Python?

Il existe plusieurs approches qui affectent un seul processus, l'environnement ou une seule ligne de code.

Je démontre chacun.

Pour tout le processus

En utilisant le -O flag (O majuscule) désactive toutes les instructions assert dans un processus.

Par exemple:

$ python -Oc "assert False"

$ python -c "assert False"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError

Notez que par désactiver, je veux dire qu'il n'exécute pas non plus l'expression qui le suit:

$ 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

Pour l'environnement

Vous pouvez également utiliser une variable d'environnement pour définir cet indicateur.

Cela affectera tous les processus qui utilisent ou héritent de l'environnement.

Par exemple, dans Windows, définir puis effacer la variable d'environnement:

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

Idem sous Unix (en utilisant set et nset pour les fonctionnalités respectives)

Point unique dans le code

Vous continuez votre question:

si une assertion échoue, je ne veux pas qu'elle lance une AssertionError, mais continue.

Si vous voulez que le code qui ne s'exécute pas, vous pouvez intercepter soit vous assurer que le flux de contrôle n'atteint pas l'assertion, par exemple:

if False:
    assert False, "we know this fails, but we don't get here"

ou vous pouvez attraper l'erreur d'assertion:

try:
    assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
    print(repr(e))

qui imprime:

AssertionError('this code runs, fails, and the exception is caught')

et vous continuerez à partir du moment où vous avez géré le AssertionError.

Références

De la documentation assert :

Une déclaration d'affirmation comme celle-ci:

assert expression #, optional_message

Est équivalent à

if __debug__:
    if not expression: raise AssertionError #(optional_message)

Et,

la variable intégrée __debug__ est True dans des circonstances normales, False lorsque l'optimisation est demandée (option de ligne de commande -O).

et plus loin

Affectations à __debug__ sont illégaux. La valeur de la variable intégrée est déterminée au démarrage de l'interpréteur.

À partir des documents d'utilisation:

- O

Activez les optimisations de base. Cela change l'extension de nom de fichier pour les fichiers compilés (bytecode) de .pyc en .pyo. Voir aussi PYTHONOPTIMIZE.

et

[~ # ~] pythonoptimize [~ # ~]

Si ce paramètre est défini sur une chaîne non vide, cela équivaut à spécifier le -O option. S'il est défini sur un entier, cela équivaut à spécifier -O plusieurs fois.

60
Aaron Hall

Appelez Python avec le drapeau -O:

test.py:

assert(False)
print 'Done'

Production:

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
57
Mark Rushakoff

Les deux réponses déjà données sont valides (appelez Python avec soit -O ou -OO sur la ligne de commande).

Voici la différence entre eux:

  • -O Activez les optimisations de base. Cela change l'extension de nom de fichier pour les fichiers compilés (bytecode) de .pyc en .pyo.

  • -OO Jeter les docstrings en plus au -O optimisations.

(De la documentation Python )

15
Michael Currie

Utilisation python -O:

$ python -O
>>> assert False
>>> 
7
John Millikin

Vous devez [~ # ~] pas [~ # ~] désactiver (la plupart) les assertions. Ils captent des erreurs imprévues lorsque l'attention est ailleurs. Voir la règle 5 dans "La puissance de dix" .

Au lieu de cela, gardez certains contrôles d'assertion coûteux par quelque chose comme:

import logging
logger = logging.getLogger(__name__)

if logger.getEffectiveLevel() < logging.DEBUG:
    ok = check_expensive_property()
    assert ok, 'Run !'

Une façon de conserver les assertions importantes et de permettre l'optimisation des instructions assert consiste à les augmenter dans une instruction de sélection:

if foo_is_broken():
    raise AssertionError('Foo is broken!')
3
Ioannis Filippidis

L'exécution en mode optimisé devrait le faire:

python -OO module.py
2
FogleBird