2011-12-28 11 views
10

Sto eseguendo uno script python da un altro software (fornisce un'interfaccia python per manipolare le sue strutture dati).Disabilitare asser python() senza -0 flag

Sto ottimizzando il mio codice per la velocità e vorrei vedere quale impatto sulle prestazioni hanno i miei assert.

Non riesco a utilizzare python -O. Quali altre opzioni ho, per disabilitare in modo programmatico tutti gli asserzioni nel codice Python? La variabile __debug__ (che è controllata da -O bandiera) non possono essere assegnati a :(

risposta

9

The docs say,

Il valore per la variabile incorporata [__debug__] è determinato quando l'interprete inizia.

quindi, se non è possibile controllare come viene avviato l'interprete python, quindi sembra che non è possibile disabilitare asserzione.

Ecco alcune altre opzioni:

  1. Il modo più sicuro è rimuovere manualmente tutte le istruzioni di asserzione.
  2. Se tutte le istruzioni Assert si verificano sulle linee da soli, allora forse si potrebbe rimuoverli con

    sed -i 's/assert /pass #assert /g' script.py 
    

    Nota che questo storpiare il codice se altro codice viene dopo l'asserzione. Ad esempio, il comando sed sopra voluto commentare-out la return in una linea come questa:

    assert x; return True 
    

    che avrebbe cambiato la logica del programma.

    Se si dispone di codice come questo, sarebbe probabilmente meglio rimuovere manualmente gli asserzioni.

  3. Ci potrebbe essere un modo per rimuoverli programmazione analizzando lo script con il modulo tokenize, ma scrivere un programma per rimuovere afferma può richiedere più tempo di quanto ci vorrebbe per manualmente rimuovere la sostiene, soprattutto se questo è un lavoro di una volta.

  4. Se l'altro pezzo di software accetta i file .pyc, poi c'è un trucco sporco che sembra funzionare sulla mia macchina, anche se nota a Python core developer warns against this (Vedi il commento di Éric Araujo su 2011-09-17). Supponiamo che lo script sia chiamato script.py.

    • creare uno script temporaneo chiamato, per esempio, temp.py:

      import script 
      
    • Run python -O temp.py. Questo crea script.pyo.
    • Spostare script.py e script.pyc (se esiste) dal vostro PYTHONPATH o qualunque directory gli altri software sta leggendo per trovare lo script .
    • Rename script.pyo ->script.pyc.

    Ora, quando gli altri software cerca di importare lo script, sarà solo trovare il file pyc, che ha l'afferma rimosso.

    Per esempio, se script.py si presenta così:

    assert False 
    print('Got here') 
    

    poi correre python temp.py stamperà Got here invece di sollevare un AssertionError.

+0

piccola correzione: 's/assert/pass # assert/g. Altrimenti "if" si ramifica con una sola affermazione "assert' non verrà compilato :) – pbp

+0

Grazie; questa è una buona idea. – unutbu

0

Come @unutbu descrive, non esiste un modo ufficiale per farlo. Tuttavia, una strategia semplice è quello di definire una bandiera come _test da qualche parte (ad esempio, come argomento chiave di una funzione, o come una variabile globale in un modulo), quindi includere questo nelle istruzioni assert come segue:

def f(x, _test=True): 
    assert not _test or x > 0 
    ... 

Quindi, se necessario, è possibile disabilitare gli asserti in quella funzione.

f(x, _test=False) 
1

Si può essere in grado di fare questo con una variabile d'ambiente, come descritto in this other answer. L'impostazione di PYTHONOPTIMIZE=1 equivale all'avvio di Python con l'opzione -O. A titolo di esempio, questo funziona in Blender 2.78, che incorpora Python 3.5:

blender --python-expr 'assert False; print("foo")' 

PYTHONOPTIMIZE=1 blender --python-expr 'assert False; print("foo")' 

I primi comando stampa un traceback, mentre il secondo si limita a stampare "foo".

Problemi correlati