在Windows下debug程式時,有時候會遇到debug的輸出實在太多,難以尋找有用的資訊時,可以用OutputDebugString這個function將輸出導到debugger去。

但是在python下要怎麼做這件事呢?

我們可以ctypes這個模組來load OutputDebugString這個function,如下所示:

import ctypes funcA = ctypes.windll.kernel32.OutputDebugStringA funcW = ctypes.windll.kernel32.OutputDebugStringW funcA('testing') funcW(u'testing')

其中因為OutputDebugString有unicode和non-unicode兩個版本,分別是OutputDebugStringW和OutputDebugStringA。因此對python的string和unicode string分別呼叫不同的function。

最後,將這個功能加到上一篇的Logger裡,就是下面的code了:

import inspect import os class Logger( object): LEVEL_MESSAGE, LEVEL_WARNING, LEVEL_ERROR, LEVEL_CRITICAL = range( 4) LEVEL_MIN_VALUE = LEVEL_MESSAGE LEVEL_MAX_VALUE = LEVEL_CRITICAL @staticmethod def __getLevelName( level): if level == Logger.LEVEL_MESSAGE: return 'MESSAGE' elif level == Logger.LEVEL_WARNING: return 'WARNING' elif level == Logger.LEVEL_ERROR: return 'ERROR' elif level == Logger.LEVEL_CRITICAL: return 'CRITICAL' else: return 'UNKNOWN' __slots__ = ( '__logLevel', '__debugStream') def __init__( self, logLevel = LEVEL_WARNING, enableWinDebug = False): self.__initVariables( logLevel) if os.name == 'nt' and enableWinDebug: self.__initWinDebug() def __initVariables( self, logLevel): self.__logLevel = logLevel self.__debugStream = None def __initWinDebug( self): import ctypes self.__debugStream = { str: ctypes.windll.kernel32.OutputDebugStringA, unicode: ctypes.windll.kernel32.OutputDebugStringW} @property def logLevel( self): return self.__logLevel @logLevel.setter def logLevel( self, logLevel): if logLevel < Logger.LEVEL_MIN_VALUE or Logger.LEVEL_MAX_VALUE < logLevel: raise ValueError, 'Invalid Log Level(%d)' % logLevel self.__logLevel = logLevel def log( self, logLevel, message, reverseStackCount = 1): if logLevel >= self.logLevel: stack = inspect.stack() if len( stack) >= reverseStackCount: frame = stack[ reverseStackCount] file = os.path.split( frame[ 1])[ 1] output = '[%s] [%s:%d] [%s] %s' % ( Logger.__getLevelName( logLevel), file, frame[ 2], frame[ 3], message) if self.__debugStream: self.__debugStream[ type( output)]( output) print output def message( self, message): self.log( Logger.LEVEL_MESSAGE, message, reverseStackCount = 2) def warning( self, message): self.log( Logger.LEVEL_WARNING, message, reverseStackCount = 2) def error( self, message): self.log( Logger.LEVEL_ERROR, message, reverseStackCount = 2) def critical( self, message): self.log( Logger.LEVEL_CRITICAL, message, reverseStackCount = 2)

arrow
arrow
    全站熱搜

    Aion 發表在 痞客邦 留言(0) 人氣()