2009-04-02 1 views
8

Я запускаю Python 2.4 в игровом движке, и я хочу иметь возможность отключать все отпечатки, если это необходимо. Например, я хотел бы иметь отпечатки для сборки отладки, а затем отключен для сборки релиза. Также важно, чтобы он был настолько прозрачным, насколько это возможно.Каков наилучший способ переключения изображений на Python?

Мое решение для этого в коде C двигателя имеет функцию printf внутри макроса vararg и определяет это, чтобы ничего не делать в сборке выпуска.

Это мое текущее решение:

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

Это позволяет легко переключать распечатки, но, возможно, лучший способ форматирования строки. Моя основная проблема заключается в том, что на самом деле это добавляет намного больше вызовов функций в программу.

Мне интересно, есть ли что-нибудь, что можно сделать для того, как работает ключевое слово print?

+0

вместо цикл, вы можете использовать 'печать "" .join (арг)' –

+0

упс, которые должны были напечатать "" .join (Карта (ул, Args)) –

+0

Тем не менее, используя 2,4? –

ответ

12

Да, вы можете назначить sys.stdout на все, что захотите. Создать небольшой класс с write метод, который ничего не делает:

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

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

С той же техникой вы можете также отпечатки вошедшего в файл, установив sys.stdout на открытый файловый объект.

+0

Не забудьте 'backup' sys.stdout, если вы хотите снова включить его позже. _stdout = sys.stdout; sys.stdout = DevNull() –

+0

С такими модулями, как «регистрация», этот метод кажется немного смешным. –

+0

«Смешно» немного над вершиной, но я получаю вашу точку. Возможно, я должен был назвать вопрос «самый простой способ переключения отпечатков»? –

3

Не используйте печать, но создайте класс консоли, который обрабатывает всю печать. Просто звоните на консоль, и консоль может решить, действительно ли их печатать. Класс консоли также полезен для таких вещей, как сообщения об ошибках и предупреждениях, или перенаправление туда, куда идет выход.

+0

+1: использование регистрации или рулона. Но не используйте печать. –

+0

Да, стоит посмотреть существующий модуль регистрации. В зависимости от объема проекта небольшой класс может быть достаточно. –

+0

Встроенный модуль регистрации очень хорош. –

8

logging module является «лучшим» способом .. хотя я довольно часто просто использовать что-то простое, как ..

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

Я знаю ответ уже отмечен как правильный, но Python имеет флаг отладки, обеспечивает более чистое решение. Вы можете использовать его как это:

if __debug__: 
    print "whoa" 

Если вы вызываете Python с -O или -со (как обычно для сборки релиза), __debug__ устанавливается в False. Что еще лучше, так это то, что __debug__ - особый случай для переводчика; он фактически вычеркнет этот код, когда он напишет файлы pyc/pyo, в результате получившийся код будет меньше/быстрее. Обратите внимание, что вы не можете назначать значения __debug__, поэтому он полностью основан на этих аргументах командной строки.

+0

+1: Это полезно знать, даже если его немного больше усилий для реализации. –

+0

Это позор, когда флаг debug включен, когда вы просто выполняете python ./thescript.py (вместо использования флага -d отладки) – dbr

0

Я ответил на этот вопрос на different post но вопрос был отмечен дубликат:

во всяком случае, вот что я хотел бы сделать:

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 

, к сожалению, вы не можете держать синтаксис py2 печати print 'foo'

+0

Хорошо работает. Но как функция печати знает о 'enable_print', если она не является глобальной и не передана в качестве аргумента? – Pyderman

1

Если вы действительно хотите, чтобы переключить печать:

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

Однако я рекомендую использовать только код print. Используйте logging для реальных приложений, таких как исходный вопрос.Это позволяет использовать скользящую шкалу подробностей, поэтому вы можете иметь только важные протоколирования или более подробные записи обычно менее важных деталей.

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

Например, использование может заключаться в том, чтобы отлаживать журналы в вашем коде. Тогда, чтобы заставить замолчать их, изменять свой уровень на более высокий уровень, один из INFO, WARN или WARNING, ERROR или CRITICAL или FATAL

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

В скрипте вы хотите просто установить это в basicConfig, как это :

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

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

Более сложное использование протоколирования можно найти in the docs.