Come disabilito le asserzioni in Python?
Cioè, se un'asserzione fallisce, non voglio che ne venga lanciata una AssertionError
, ma che continui.
Come lo faccio?
Risposte:
Come disabilito le asserzioni in Python?
Esistono più approcci che influiscono su un singolo processo, l'ambiente o una singola riga di codice.
Dimostro ciascuno.
L'uso del -O
flag (O maiuscola) disabilita tutte le istruzioni di asserzione in un processo.
Per esempio:
$ python -Oc "assert False"
$ python -c "assert False"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AssertionError
Nota che per disabilitare intendo anche che non esegue l'espressione che lo segue:
$ 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
Puoi anche usare una variabile d'ambiente per impostare questo flag.
Ciò influenzerà ogni processo che utilizza o eredita l'ambiente.
Ad esempio, in Windows, impostare e quindi cancellare la variabile d'ambiente:
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
Lo stesso in Unix (usando set e unset per le rispettive funzionalità)
Continui la tua domanda:
se un'asserzione fallisce, non voglio che generi un AssertionError, ma che continui.
Se si desidera che il codice non venga eseguito, è possibile intercettare o assicurarsi che il flusso di controllo non raggiunga l'asserzione, ad esempio:
if False:
assert False, "we know this fails, but we don't get here"
oppure puoi rilevare l'errore di asserzione:
try:
assert False, "this code runs, fails, and the exception is caught"
except AssertionError as e:
print(repr(e))
che stampa:
AssertionError('this code runs, fails, and the exception is caught')
e continuerai dal punto in cui hai gestito il file AssertionError
.
Un'affermazione assert come questa:
assert expression #, optional_message
È equivalente a
if __debug__:
if not expression: raise AssertionError #(optional_message)
E,
la variabile incorporata
__debug__
èTrue
in circostanze normali,False
quando viene richiesta l'ottimizzazione (opzione della riga di comando-O
).
e inoltre
Le assegnazioni a
__debug__
sono illegali. Il valore per la variabile incorporata viene determinato all'avvio dell'interprete.
Dai documenti di utilizzo:
Attiva le ottimizzazioni di base. Questo cambia l'estensione del nome del file per i file compilati (bytecode) da .pyc a .pyo. Vedi anche PYTHONOPTIMIZE.
e
Se è impostato su una stringa non vuota, è equivalente a specificare l'
-O
opzione. Se impostato su un numero intero, equivale a specificare-O
più volte.
if False: assert False
) o puoi rilevare l'errore di asserzione. Queste sono le tue scelte. Aggiornata la risposta per rispondere alla tua domanda.
foo()
e asserzioni SPEGNIMENTO: with skip_assertion(): foo()
. Il vantaggio di questo è che non devo aggiungere un altro flag alla funzione
Assert
oggetti con gli Pass
oggetti). Un gestore di contesto non funzionerebbe direttamente per questo, ma potresti avere una sorta di meccanismo che utilizza funzioni decorate in quel modo. Indipendentemente da ciò, non lo consiglio. Sospetto che il motivo per cui lo desideri è che stai chiamando un codice che non controlli e ottieni AssertionErrors. In tal caso, probabilmente dovrai trovare una soluzione diversa.
Chiama Python con il flag -O:
test.py:
assert(False)
print 'Done'
Produzione:
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
Entrambe le due risposte già fornite sono valide (chiama Python con -O
o -OO
sulla riga di comando).
Ecco la differenza tra loro:
-O
Attiva le ottimizzazioni di base. Questo cambia l'estensione del nome del file per i file compilati (bytecode) da .pyc a .pyo.
-OO
Elimina le stringhe di documentazione oltre alle -O
ottimizzazioni.
(Dalla documentazione di Python )
Usa python -O
:
$ python -O
>>> assert False
>>>
Si dovrebbe NON disattivare (la maggior parte) affermazioni. Catturano errori imprevisti quando l'attenzione è altrove. Vedere la regola 5 in "Il potere di dieci" .
Invece, custodisci alcuni costosi controlli di asserzione con qualcosa del tipo:
import logging
logger = logging.getLogger(__name__)
if logger.getEffectiveLevel() < logging.DEBUG:
ok = check_expensive_property()
assert ok, 'Run !'
Un modo per mantenere le asserzioni importanti e consentire l' assert
ottimizzazione delle istruzioni è aumentarle all'interno di un'istruzione di selezione:
if foo_is_broken():
raise AssertionError('Foo is broken!')
__debug__
False ma non è consentito.