Comment désactiver les assertions en Python?
Autrement dit, si une assertion échoue, je ne veux pas qu'elle lève un AssertionError
, mais qu'elle continue.
Comment je fais ça?
Réponses:
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.
L'utilisation de l' -O
indicateur (O majuscule) désactive toutes les instructions d'assertion 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
Vous pouvez également utiliser une variable d'environnement pour définir cet indicateur.
Cela affectera chaque processus qui utilise ou hérite de l'environnement.
Par exemple, sous 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 unset pour les fonctionnalités respectives)
Vous continuez votre question:
si une assertion échoue, je ne veux pas qu'elle lève une AssertionError, mais qu'elle continue.
Si vous souhaitez que le code qui échoue à s'exercer, vous pouvez 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 fichier AssertionError
.
Une déclaration d'assert 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__
estTrue
dans des circonstances normales,False
lorsqu'une optimisation est demandée (option de ligne de commande-O
).
et plus loin
Les attributions à
__debug__
sont illégales. La valeur de la variable intégrée est déterminée au démarrage de l'interpréteur.
À partir des documents d'utilisation:
Activez les optimisations de base. Cela change l'extension de nom de fichier pour les fichiers compilés (bytecode) de .pyc à .pyo. Voir aussi PYTHONOPTIMIZE.
et
Si cela est défini sur une chaîne non vide, cela équivaut à spécifier l'
-O
option. S'il est défini sur un entier, cela équivaut à spécifier-O
plusieurs fois.
if False: assert False
), soit attraper l'erreur d'assertion. Ce sont vos choix. Mise à jour de la réponse pour répondre à votre question.
foo()
et assertions mise hors circuit: with skip_assertion(): foo()
. L'avantage de ceci étant que je n'ai pas à ajouter un autre drapeau sur la fonction
Assert
objets par des Pass
objets). Un gestionnaire de contexte ne fonctionnerait pas directement pour cela, mais vous pourriez avoir une sorte de mécanisme qui utilise des fonctions décorées de cette manière. Quoi qu'il en soit, je ne le recommande pas. Je soupçonne que votre raison de vouloir le faire est que vous appelez du code que vous ne contrôlez pas et que vous obtenez des AssertionErrors. Si tel est le cas, vous devrez probablement trouver un correctif différent.
Appelez Python avec l'indicateur -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
Les deux réponses déjà données sont valides (appelez Python avec l'un -O
ou l' autre -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 à .pyo.
-OO
Supprimez les docstrings en plus des -O
optimisations.
(De la documentation Python )
Utilisez python -O
:
$ python -O
>>> assert False
>>>
Vous ne devez PAS désactiver (la plupart) des assertions. Ils détectent des erreurs imprévues lorsque l'attention est ailleurs. Voir la règle 5 dans «Le pouvoir de dix» .
Au lieu de cela, protégez certains contrôles d'assertions 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 d'autoriser assert
l'optimisation des instructions consiste à les lever dans une instruction de sélection:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
sur False mais ce n'est pas autorisé.