Bedingt evaluierte Debug-Anweisungen in Python

10

Python hat einige Möglichkeiten, "trace" -Ausgaben zu drucken. print , import logging , stdout.write kann verwendet werden, um Debugging-Informationen zu drucken, aber alle haben einen Nachteil: Auch wenn der Schwellenwert des Loggers zu hoch ist oder der Stream geschlossen ist, wertet Python die Argumente für die print-Anweisung aus . ( Strict Evaluation ) Dies könnte ein Zeichenfolgenformat oder mehr kosten.

Die offensichtliche Lösung besteht darin, den String-erzeugenden Code in ein Lambda zu schreiben und unsere eigene Logging-Funktion zu verwenden, um das Lambda bedingt aufzurufen (überprüft die Variable __debug__ builtin), die bei jedem Start von python auf False gesetzt wird -O für Optimierungen):

%Vor%

Der Vorteil besteht nicht darin, str(currentItem) und string.format in Release-Builds aufzurufen, und der Nachteil besteht darin, dass lambda: bei jeder Logging-Anweisung eingegeben werden muss.

Pythons assert -Anweisung wird speziell vom Python-Compiler behandelt. Wenn Python mit -O ausgeführt wird, werden alle assert-Anweisungen ohne Auswertung verworfen. Sie können dies ausnutzen, um eine weitere bedingt ausgewertete Protokollierungsanweisung zu erstellen:

%Vor%

Diese Zeile wird nicht ausgewertet, wenn Python mit -O gestartet wird.

Die Kurzschlussoperatoren 'und' oder 'können sogar verwendet werden:

%Vor%

Aber jetzt haben wir bis zu 28 Zeichen plus den Code für die Ausgabezeichenfolge.

Die Frage, zu der ich komme: Gibt es Standard-Python-Anweisungen oder -Funktionen, die dieselben Eigenschaften für die bedingte Auswertung haben wie die assert -Anweisung? Oder hat jemand Alternativen zu den hier vorgestellten Methoden?

    
codewarrior 03.10.2011, 11:39
quelle

4 Antworten

2

Ich frage mich, wie sehr sich ein Aufruf von logging.debug auf die Leistung auswirkt, wenn keine Handler vorhanden sind.

Allerdings wird die if __debug__: -Anweisung nur einmal ausgewertet, selbst im Rumpf einer Funktion

%Vor%

und der Logger kann die Nachricht für Sie formatieren, indem Sie den Operator für die Zeichenfolgenformatierung verwenden. Hier ein leicht abgewandeltes Beispiel aus der logging.debug Dokumentation

%Vor%

In diesem Fall wird der Nachrichtenstring niemals ausgewertet, wenn die Optimierungen ausgeschaltet sind.

    
mg. 03.10.2011, 19:15
quelle
3

Wenn all Ihre Debug-Funktion eine Zeichenfolge benötigt, ändern Sie sie in eine Formatzeichenfolge und die Argumente:

%Vor%

wird

%Vor%

und

%Vor%

Dies hat alle Vorteile Ihrer ersten Option, ohne dass ein Lambda benötigt wird und wenn der if __debug__: aus der Funktion entfernt wird, so dass er nur einmal getestet wird, wenn das enthaltene Modul geladen ist, ist der Aufwand der Anweisung gerade ein Funktionsaufruf.

    
Dan D. 03.10.2011 11:50
quelle
0

alle Standard-Python-Anweisungen oder -Funktionen mit dem gleichen bedingten Verhalten wie assert - & gt; Nein, soweit ich weiß.

Beachten Sie, dass von logging functions keine String-Interpolation ausgeführt wird, wenn der Schwellenwert zu hoch ist (Sie zahlen jedoch immer noch für den Methodenaufruf und einige der darin enthaltenen Prüfungen).

Sie können den Vorschlag von Dan D. erweitern, indem Sie logging.logger beim Starten des Codes anpassen:

%Vor%

und verwenden Sie dann wie gewohnt die Protokollierung. Sie können sogar den ersten Test ändern, um das Ersetzen der Protokollierungsmethoden auch im nicht optimierten Modus zu ermöglichen

    
gurney alex 03.10.2011 12:03
quelle
0

Sie können die Methode eval verwenden:

%Vor%     
Gary van der Merwe 03.10.2011 12:06
quelle

Tags und Links