webentwicklung-frage-antwort-db.com.de

Wie würden Sie das Äquivalent von Präprozessoranweisungen in Python ausführen?

Gibt es eine Möglichkeit, die folgenden Präprozessoranweisungen in Python auszuführen?

#if DEBUG

< do some code >

#else

< do some other code >

#endif
52
intrepion

Es gibt __debug__, einen speziellen Wert, den der Compiler vorverarbeitet. 

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

__debug__ wird vom Compiler durch eine konstante 0 oder 1 ersetzt, und der Optimierer entfernt if 0:-Zeilen, bevor Ihre Quelle interpretiert wird.

97
habnabit

Ich habe einen Python-Präprozessor namens Pypreprocessor geschrieben, der genau das tut, was Sie beschreiben.

Die Quelle und Dokumentation ist auf Google Code verfügbar .

Das Paket kann auch über PYPI heruntergeladen/installiert werden.

Hier ist ein Beispiel, um zu erreichen, was Sie beschreiben.

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 kann weit mehr als nur die Vorverarbeitung im laufenden Betrieb. Weitere Anwendungsbeispiele finden Sie unter Google Code.

Update: Weitere Informationen zu Pypreprocessor

Die Art und Weise, wie ich die Vorverarbeitung verwende, ist einfach. Aus dem obigen Beispiel importiert der Präprozessor ein Pypreprocessor-Objekt, das im Pypreprocessor-Modul erstellt wird. Wenn Sie parse () für den Präprozessor aufrufen, verwendet es die Datei, in die es importiert wird, selbst und verwendet eine temporäre Kopie von sich selbst, die den gesamten Präprozessorcode auskommentiert (um zu vermeiden, dass der Präprozessor sich in einer Endlosschleife rekursiv aufruft) und kommentiert alle nicht verwendeten Teile aus.

Das Auskommentieren der Zeilen ist im Gegensatz zu dem Entfernen dieser Zeilen erforderlich, um die Zeilennummern für die Fehlerrückverfolgung beizubehalten, wenn das Modul eine Ausnahme auslöst oder abstürzt. Und ich bin sogar so weit gegangen, das Fehler-Traceback neu zu schreiben, um den korrekten Dateinamen des abgestürzten Moduls anzugeben.

Dann wird die generierte Datei, die den nachbearbeiteten Code enthält, im laufenden Betrieb ausgeführt.

Der Vorteil dieser Methode besteht darin, eine Reihe von if-Anweisungen inline in den Code einzufügen. Es wird keine Ausführungszeit verschwendet, wenn unnötige Anweisungen ausgewertet werden, da die auskommentierten Teile des Codes aus den kompilierten .pyc-Dateien ausgeschlossen werden.

Der Nachteil (und mein ursprünglicher Grund für die Erstellung des Moduls) besteht darin, dass Sie weder Python 2x als auch Python 3x in derselben Datei ausführen können, da der Pythons-Interpreter vor der Ausführung des Codes eine vollständige Syntaxprüfung durchführt und vor der Ausführung sämtlichen versionsspezifischen Codes ablehnt Präprozessor darf :: sigh :: ausführen. Mein ursprüngliches Ziel war es, 2x und 3x Code nebeneinander in derselben Datei entwickeln zu können, der je nach Ausführung versionsspezifischer Bytecode erstellt.

In beiden Fällen ist das Präprozessormodul immer noch sehr nützlich, um gängige Vorverarbeitungsfunktionen im c-Stil zu implementieren. Außerdem kann der Präprozessor den nachverarbeiteten Code zur späteren Verwendung in einer Datei ausgeben, wenn Sie möchten.

Wenn Sie eine Version generieren möchten, die alle Präprozessoranweisungen sowie alle ausgeschlossenen #ifdefs enthält, müssen Sie lediglich ein Flag im Präprozessorcode setzen, bevor Sie parse () aufrufen. Dies macht das Entfernen von unerwünschtem Code aus einer versionsspezifischen Quelldatei zu einem einstufigen Prozess (Durchforsten durch den Code und manuelles Entfernen von if-Anweisungen). 

31
Evan Plaice

Ich vermute, du wirst diese Antwort hassen. So machen Sie das in Python

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

Da Python ein Interpreter ist, gibt es keinen Vorverarbeitungsschritt und keinen besonderen Vorteil einer speziellen Syntax. 

22
Charlie Martin

Sie können den Präprozessor in Python verwenden. Führen Sie einfach Ihre Skripts über den cpp (C-Preprocessor) in Ihrem bin-Verzeichnis aus. Ich habe dies jedoch mit Lua gemacht und die Vorteile der einfachen Interpretation haben die komplexere Zusammenstellung IMHO aufgewogen.

10
Robert Gould

Sie können nur die normalen Sprachkonstrukte verwenden:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
3
phihag

Eine alternative Methode ist die Verwendung eines Bash-Skripts, um Codeabschnitte auszukommentieren, die nur für das Debugging relevant sind. Im Folgenden finden Sie ein Beispielskript, in dem Zeilen mit der Anweisung '#DEBUG' auskommentiert werden. Es kann auch diese Kommentarmarken wieder entfernen.

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
slierp
  • Python kann keine Elemente aus Arrays entfernen.
  • C-Precompiler behandeln # nicht! oder andere Zeilen, die nach Bedarf mit # beginnen.
  • pypreprocessor scheint pythonspezifisch zu sein

Verwenden Sie stattdessen eine gewöhnliche m4 wie folgt:

ifelse(DEBUG,True,dnl`
  < do some code >
dnl,dnl`
  < do some other code >dnl
')

ifelse(
  M4_CPU,x86_64,`
    < do some code specific for M4_CPU >
',M4_CPU,arm,`
    < do some code specific for M4_CPU >
',M4_CPU,ppc64le,`
    < do some code specific for M4_CPU >
')

ifelse(
  M4_OS,windows,`
    < do some code specific for M4_OS >
  ',M4_OS,linux,`
    < do some code specific for M4_OS >
  ',M4_OS,Android,`
    < do some code specific for M4_OS >
')

m4 -D DEBUG = True -D M4_OS = Android -D M4_CPU = Arm test.py.m4> test.py

0