2011-12-28 3 views
10

Estoy ejecutando un script de python desde dentro de un software diferente (proporciona una interfaz de python para manipular sus estructuras de datos).Deshabilitar la afirmación de python() sin -0 flag

Estoy optimizando mi código de velocidad y me gustaría ver qué impacto en el rendimiento tienen mis afirmaciones.

No puedo utilizar python -O. ¿Qué otras opciones tengo para deshabilitar programáticamente todas las afirmaciones en el código python? La variable __debug__ (que se elimina por -O bandera) no se pueden asignar a :(

Respuesta

9

The docs say,

El valor de la variable incorporada [__debug__] se determina cuando el intérprete comienza.

Por lo tanto, si no se puede controlar la forma en que se inicia el intérprete de Python, entonces parece que no se puede deshabilitar aserción.

Aquí hay algunas otras opciones:

  1. La manera más segura es eliminar manualmente todas las declaraciones de afirmación.
  2. Si todos los estados de cuenta de aserción se producen en las líneas de ellos mismos, entonces Tal vez podría eliminarlos con

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

    Tenga en cuenta que esto va a destrozar su código si otro código se produce después de la aserción. Por ejemplo, el comando sed anterior podría comentar de salida del return en una línea como la siguiente:

    assert x; return True 
    

    que pueda modificar la lógica de su programa.

    Si tiene un código como este, probablemente sería mejor eliminar manualmente las afirmaciones.

  3. Puede haber una manera de eliminarlos mediante programación mediante el análisis de la secuencia de comandos con el módulo tokenize, pero escribir un programa de este tipo a quitar afirma puede tomar más tiempo que se tardaría en forma manual retire el afirma, sobre todo si este es un trabajo de una sola vez.

  4. Si la otra pieza de software acepta .pyc archivos, entonces no es un truco sucio que parece funcionar en mi máquina, aunque tenga en cuenta a Python core developer warns against this (Véase el comentario de Eric Araujo en 2011-09-17). Supongamos que su script se llama script.py.

    • hacer un script temporal denominado, por ejemplo, temp.py:

      import script 
      
    • Run python -O temp.py. Esto crea script.pyo.
    • Mueva script.py y script.pyc (si existe) fuera de su PYTHONPATH o cualquier directorio que el otro software esté leyendo para encontrar su script .
    • Renombrar script.pyo ->script.pyc.

    Ahora, cuando el resto del software intenta importar la secuencia de comandos, se sólo se encuentra el archivo pyc, que tiene la afirma eliminado.

    Por ejemplo, si script.py se ve así:

    assert False 
    print('Got here') 
    

    luego corriendo python temp.py Ahora imprimir Got here en lugar de elevar un AssertionError.

+0

fix pequeño: 's/assert/pass # assert/g. De lo contrario, las ramas 'if' con una sola declaración' assert' no compilarán :) – pbp

+0

Gracias; es una buena idea. – unutbu

0

Como describe @unutbu, no hay una forma oficial de hacerlo. Sin embargo, una simple estrategia es definir una bandera como _test algún lugar (por ejemplo, como argumento de palabra clave a una función, o como una variable global en un módulo), a continuación, incluir esto en sus declaraciones de aserción de la siguiente manera:

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

Luego puede desactivar las afirmaciones en esa función si es necesario.

f(x, _test=False) 
1

Puede hacer esto con una variable de entorno, como se describe en this other answer. La configuración PYTHONOPTIMIZE=1 es equivalente a iniciar Python con la opción -O. A modo de ejemplo, esto funciona en Blender 2,78, que incorpora Python 3.5:

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

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

Los primeros comando imprime un rastreo, mientras que el segundo sólo imprime "foo".

Cuestiones relacionadas