Comment feriez-vous l'équivalent des directives préprocesseur en Python?

y a-t-il un moyen de faire les directives préprocesseur suivantes en Python?

#if DEBUG

< do some code >

#else

< do some other code >

#endif
51
demandé sur intrepion 2009-01-27 04:10:43

6 réponses

il y a __debug__ , qui est une valeur spéciale que le compilateur traite à l'avance.

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

__debug__ sera remplacé par une constante 0 ou 1 par le compilateur, et l'optimiseur supprimera toutes les lignes if 0: avant que votre source ne soit interprétée.

93
répondu habnabit 2009-01-27 03:25:06

j'ai écrit un préprocesseur python appelé pypreprocesseur qui fait exactement ce que vous décrivez.

la source et la documentation sont disponibles sur Google Code .

le paquet peut également être téléchargé/installé via le PYPI .

voici un exemple pour accomplir ce que vous décrivez.

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

pypreprprocessor est capable de beaucoup plus qu'un simple prétraitement à la volée. Voir plus d'exemples de cas d'utilisation découvrez le projet sur Google Code.

mise à jour: plus D'informations sur le processeur

la façon dont je réalise le prétraitement est simple. À partir de l'exemple ci-dessus, le préprocesseur importe un objet du processeur pyprepreessor qui est créé dans le module du processeur pyprepreessor. Lorsque vous appelez parse() sur le préprocesseur auto-consomme le fichier est importé dans et génère une copie temporaire de lui-même qui commente tout le code du préprocesseur (pour éviter que le préprocesseur ne s'appelle récursivement dans une boucle infinie) et commente toutes les parties inutilisées.

commentant les lignes est, au lieu de les supprimer, est nécessaire pour préserver les numéros de ligne sur les tracebacks d'erreur si le module lance une exception ou se bloque. Et j'ai même été jusqu'à réécrire l'erreur de traçage rapport reflètent le bon nom de fichier de l' module qui s'est écrasé.

ensuite, le fichier généré contenant le code post-traité est exécuté à la volée.

l'avantage d'utiliser cette méthode en ajoutant simplement un tas d'instructions if inline dans le code est, il n'y aura pas de temps d'exécution perdu à évaluer les instructions inutiles parce que les parties commentées du code seront exclues de la compilation .fichiers pyc.

l'inconvénient (et ma raison originale pour créer le module) est que vous ne pouvez pas exécuter à la fois python 2x et python 3x dans le même fichier parce que l'interpréteur Python exécute une vérification complète de la syntaxe avant d'exécuter le code et rejettera tout code spécifique à la version avant que le préprocesseur ne soit autorisé à exécuter ::sigh::. Mon objectif initial était de pouvoir développer du code 2x et 3x côte à côte dans le même fichier qui créerait un bytecode spécifique à la version en fonction de ce sur quoi il tourne.

dans tous les cas, le module de préprocesseur est encore très utile pour mettre en œuvre des capacités communes de prétraitement de style c. De plus, le préprocesseur est capable d'envoyer le code post-traité dans un fichier pour une utilisation ultérieure si vous le souhaitez.

aussi, si vous voulez générer une version qui a toutes les directives du préprocesseur ainsi que toutes les #ifdefs qui sont exclus supprimés, c'est aussi simple que de définir un drapeau dans le code du préprocesseur avant d'appeler parse(). Cela rend la suppression du code indésirable d'une source spécifique à une version déposer un processus en une étape (vs parcourir le code et supprimer les instructions if manuellement).

29
répondu Evan Plaice 2010-08-25 06:20:23

je pense que vous allez détester cette réponse. La façon dont vous faites cela en Python est

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

comme python est un interpréteur, il n'y a pas d'étape de prétraitement à appliquer, et aucun avantage particulier à avoir une syntaxe spéciale.

23
répondu Charlie Martin 2009-01-27 01:14:24

vous pouvez utiliser le préprocesseur en Python. Il suffit d'exécuter vos scripts à travers le cpp (C-Preprocessor) dans votre répertoire bin. Cependant J'ai fait cela avec Lua et les avantages de l'interprétation facile ont surpassé la compilation plus complexe IMHO.

10
répondu Robert Gould 2009-01-27 01:16:14

vous pouvez simplement utiliser les constructions de langue normales:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
4
répondu phihag 2009-01-27 01:14:28

une autre méthode consiste à utiliser un script bash pour commenter les parties du code qui ne sont pertinentes que pour le débogage. Vous trouverez ci-dessous un exemple de script qui commente les lignes qui contiennent une instruction '#DEBUG'. Il peut également supprimer ces marqueurs de commentaire à nouveau.

if [ "" == "off" ]; then
  sed -e '/^#/! {/#DEBUG/ s/^/#/}' -i *.py
  echo "Debug mode to "
elif [ "" == "on" ]; then
  sed -e '/#DEBUG/ s/^#//' -i *.py
  echo "Debug mode to "
else
  echo "usage: "151900920" on | off"
fi
1
répondu slierp 2015-07-07 06:47:17