2009-04-02 16 views
8

Ich benutze Python 2.4 in einer Game Engine und möchte alle Drucke bei Bedarf ausschalten können. Zum Beispiel möchte ich die Drucke für einen Debug-Build haben und dann für einen Release-Build deaktiviert. Es ist auch wichtig, dass es so transparent wie möglich ist.Was ist der beste Weg, um Python-Drucke umzuschalten?

Meine Lösung für diese in der C-Code der Engine ist die printf-Funktion in einem Makro, und definieren, dass nichts in einem Release-Build zu tun.

Dies ist meine aktuelle Lösung:

DebugPrints = True 
def PRINT (*args): 
    global DebugPrints 
    if DebugPrints: 
     string = "" 
     for arg in args: 
      string += " " + str(arg) 
     print string 

Es macht es einfach Ausdrucke zu wechseln, aber es gibt möglicherweise einen besseren Weg, um die Zeichenfolge zu formatieren. Mein Hauptproblem ist, dass dies tatsächlich eine Menge mehr Funktionsaufrufe zum Programm hinzufügt.

Ich frage mich, ob es etwas gibt, was Sie tun können, wie das Schlüsselwort print funktioniert?

+0

statt der for-Schleife, können Sie 'print "" .join (args)' –

+0

oops, das sollte Druck gewesen sein "" .join (Karte (str, args)) –

+0

Immer noch mit 2.4? –

Antwort

12

ja, Sie können sys.stdout zuweisen, was auch immer Sie wollen. Erstellen Sie eine kleine Klasse mit einer write Methode, die nichts tut:

class DevNull(object): 
    def write(self, arg): 
     pass 

import sys  
sys.stdout = DevNull() 
print "this goes to nirvana!" 

Mit der gleichen Technik, die Sie auch durch das Setzen sys.stdout in ein geöffneten Datei-Objekt in eine Datei Abzüge angemeldet haben, können.

+0

Vergessen Sie nicht, sys.stdout zu sichern, wenn Sie es später wieder aktivieren möchten. _stdout = sys.stdout; sys.stdout = DevNull() –

+0

Mit Modulen wie "Logging" scheint diese Methode ein bisschen lächerlich. –

+0

"lächerlich" ist ein bisschen übertrieben, aber ich verstehe Ihren Standpunkt. Ich hätte vielleicht die Frage "einfachste Möglichkeit zum Umschalten von Ausdrucken" nennen sollen? –

3

Verwenden Sie nicht drucken, sondern eine Konsole-Klasse, die alle Druckvorgänge behandelt. Rufen Sie einfach die Konsole an und die Konsole kann entscheiden, ob sie tatsächlich gedruckt werden soll oder nicht. Eine Konsolenklasse ist auch nützlich für Dinge wie Fehler- und Warnmeldungen oder umleiten, wohin die Ausgabe geht.

+0

+1: Verwenden Sie Protokollierung oder rollen Sie Ihre eigenen. Aber benutze keinen Druck. –

+0

Ja, ein vorhandenes Protokollierungsmodul ist es wert, betrachtet zu werden. Je nach Umfang des Projekts kann eine kleine Klasse ausreichen. –

+0

Das integrierte Logging-Modul ist ziemlich gut. –

8

Die logging module ist der „beste“ Weg .. obwohl ich ziemlich oft nur etwas einfach zu verwenden wie ..

class MyLogger: 
    def _displayMessage(self, message, level = None): 
     # This can be modified easily 
     if level is not None: 
      print "[%s] %s" % (level, message 
     else: 
      print "[default] %s" % (message) 

    def debug(self, message): 
     self._displayMessage(message, level = "debug") 
    def info(self, message): 
     self._displayMessage(message, level = "info") 

log = MyLogger() 
log.info("test") 
10

Ich weiß eine Antwort bereits als korrekt markiert, aber Python hat einen Debug-Flag, bietet eine sauberere Lösung. Sie verwenden es wie folgt aus:

if __debug__: 
    print "whoa" 

Wenn Sie Python mit -O oder -OO aufrufen (wie gewohnt für eine Release-Build), __debug__-False gesetzt. Was noch besser ist, ist, dass __debug__ ein Sonderfall für den Interpreter ist; Es wird tatsächlich diesen Code ausstreichen, wenn er die pyc/pyo Dateien schreibt, wodurch der resultierende Code kleiner/schneller wird. Beachten Sie, dass Sie __debug__ keine Werte zuweisen können, so dass es vollständig auf diesen Befehlszeilenargumenten basiert.

+0

+1: Das ist nützlich zu wissen, auch wenn es ein wenig mehr Aufwand zu implementieren –

+0

Es ist eine Schande, die Debug-Flag ist eingeschaltet, wenn Sie einfach Python ./thescript.py (anstelle der Verwendung der-Debug-Flag) – dbr

0

ich diese Frage auf einem different post beantwortet haben aber wurde die Frage Duplikat markiert:

sowieso, hier ist was ich tun würde:

from __future__ import print_function 
DebugPrints = 0 

def print(*args, **kwargs): 
    if DebugPrints: 
     return __builtins__.print(*args, **kwargs) 

print('foo') # doesn't get printed 
DebugPrints = 1 
print('bar') # gets printed 

leider können Sie die py2 Druck Syntax nicht halten print 'foo'

+0

Funktioniert gut. Aber wie weiß die Druckfunktion über 'enable_print', wenn sie nicht global ist und nicht als Argument übergeben wurde? – Pyderman

1

Wenn Sie wirklich wollen, wechseln Druck:

>>> import sys 
>>> import os 
>>> print 'foo' 
foo 
>>> origstdout = sys.stdout 
>>> sys.stdout = open(os.devnull, 'w') 
>>> print 'foo' 
>>> sys.stdout = origstdout 
>>> print 'foo' 
foo 

Allerdings empfehle ich Ihnen nur print als Wegwerfcode zu verwenden. Verwenden Sie logging für echte Apps wie die ursprüngliche Frage beschreibt.Es ermöglicht eine gleitende Skala von Ausführlichkeit, so dass Sie nur die wichtige Protokollierung oder ausführlichere Protokollierung von normalerweise weniger wichtigen Details haben können.

>>> import logging 
>>> logging.basicConfig(level=logging.DEBUG) 
>>> logging.debug('foo') 
DEBUG:root:foo 

Zum Beispiel könnte die Verwendung von Debugging-Logs in Ihrem Code verwendet werden. Dann sie zum Schweigen zu bringen, ändern Sie Ihr Niveau auf ein höheres Niveau, von INFO, WARN oder WARNING, ERROR oder CRITICAL oder FATAL

>>> logging.root.setLevel(logging.INFO) 
>>> logging.debug('foo') 
>>> 

In einem Skript Sie dies nur festlegen möchten werden in den basicConfig wie diese :

import logging 
logging.basicConfig(level=logging.INFO) 

logging.debug('foo') # this will be silent 

Kompliziertere Nutzung der Protokollierung kann in the docs finden.


Verwandte Themen