Cómo haría usted el equivalente de las directivas de preprocesador en Python?


¿Hay alguna manera de hacer las siguientes directivas de preprocesador en Python?

#if DEBUG

< do some code >

#else

< do some other code >

#endif
Author: intrepion, 2009-01-27

6 answers

Hay __debug__, que es un valor especial que el compilador hace preprocesar.

if __debug__:
  print "If this prints, you're not running python -O."
else:
  print "If this prints, you are running python -O!"

__debug__ será reemplazado por una constante 0 o 1 por el compilador, y el optimizador eliminará cualquier línea if 0: antes de que se interprete su fuente.

 93
Author: habnabit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 03:25:06

Escribí un preprocesador de Python llamado pypreprocessor que hace exactamente lo que estás describiendo.

La fuente y la documentación están disponibles en Google Code .

El paquete también se puede descargar/instalar a través del PYPI.

Aquí hay un ejemplo para lograr lo que estás describiendo.

from pypreprocessor import pypreprocessor

pypreprocessor.parse()

#define debug

#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif

Pypreprocessor es capaz de mucho más que solo preprocesamiento sobre la marcha. Para ver más ejemplos de casos de uso, echa un vistazo al proyecto en Google Codificar.

Actualización: Más información sobre pypreprocessor

La forma en que realizo el preprocesamiento es simple. A partir del ejemplo anterior, el preprocesador importa un objeto pypreprocessor que se crea en el módulo pypreprocessor. Cuando llamas a parse () en el preprocesador, consume automáticamente el archivo al que se importa y genera una copia temporal de sí mismo que comenta todo el código del preprocesador (para evitar que el preprocesador se llame recursivamente en un infinito loop) y comenta todas las porciones no utilizadas.

Comentar las líneas es, en lugar de eliminarlas, necesario para preservar los números de línea en los rastreos de error si el módulo lanza una excepción o se bloquea. E incluso he ido tan lejos como para reescribir el rastreo de error para informar reflejar el nombre de archivo adecuado del módulo que se estrelló.

Luego, el archivo generado que contiene el código postprocesado se ejecuta sobre la marcha.

La ventaja de usar este método sobre solo agregar un montón de sentencias if en línea en el código is, no habrá tiempo de ejecución perdido evaluando sentencias inútiles porque las porciones comentadas del código serán excluidas de la compilación .archivos pyc.

El inconveniente (y mi razón original para crear el módulo) es que no puede ejecutar python 2x y python 3x en el mismo archivo porque el intérprete de pythons ejecuta una comprobación de sintaxis completa antes de ejecutar el código y rechazará cualquier código específico de la versión antes de el preprocesador puede ejecutar:: sigh::. Mi objetivo original era ser capaz de desarrollar código 2x y 3x lado a lado en el mismo archivo que crearía bytecode específico de la versión dependiendo de lo que se está ejecutando.

De cualquier manera, el módulo preprocesador sigue siendo muy útil para implementar capacidades comunes de preprocesamiento de estilo c. Así como, el preprocesador es capaz de enviar el código postprocesado a un archivo para su uso posterior si lo desea.

También, si desea generar un versión que tiene todas las directivas preprocesador, así como cualquiera de los #ifdefs que se excluyen eliminado es tan simple como establecer una bandera en el código preprocesador antes de llamar a parse(). Esto hace que la eliminación de código no deseado de un archivo de origen específico de la versión sea un proceso de un solo paso (en lugar de rastrear el código y eliminar instrucciones if manualmente).

 29
Author: Evan Plaice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-25 06:20:23

Sospecho que vas a odiar esta respuesta. La forma de hacerlo en Python es

# code here
if DEBUG:
   #debugging code goes here
else:
   # other code here.

Dado que python es un intérprete, no hay un paso de preprocesamiento que se deba aplicar, y no hay ninguna ventaja particular en tener una sintaxis especial.

 23
Author: Charlie Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 01:14:24

Puede usar el preprocesador en Python. Simplemente ejecute sus scripts a través del cpp (C-Preprocessor) en su directorio bin. Sin embargo, he hecho esto con Lua y los beneficios de la fácil interpretación han superado a la compilación más compleja IMHO.

 10
Author: Robert Gould,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 01:16:14

Puedes usar las construcciones normales del lenguaje:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
 4
Author: phihag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 01:14:28

Un método alternativo es usar un script bash para comentar partes del código que solo son relevantes para la depuración. A continuación se muestra un script de ejemplo que comenta las líneas que tienen una instrucción '#DEBUG'. También puede eliminar estos marcadores de comentario de nuevo.

if [ "$1" == "off" ]; then
  sed -e '/^#/! {/#DEBUG/ s/^/#/}' -i *.py
  echo "Debug mode to $1"
elif [ "$1" == "on" ]; then
  sed -e '/#DEBUG/ s/^#//' -i *.py
  echo "Debug mode to $1"
else
  echo "usage: $0 on | off"
fi
 1
Author: slierp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-07 06:47:17