如何在Python中进行调试打印?

Que*_*onC 4 python debugging logging python-3.x

我有一个这样的功能......

def validate_phone(raw_number, debug=False):

我希望调试标志来控制它是否输出日志语句。例如:

if (debug):
  print('Before splitting numbers', file=sys.stderr)

split_version = raw_number.split('-')

if (debug):
  print('After splitting numbers', file=sys.stderr)
Run Code Online (Sandbox Code Playgroud)

然而,该代码非常重复。处理这种 if-flag-then-log 逻辑的最干净(最干燥?)的方法是什么?

小智 6

我同意使用日志记录是在运行 python 脚本时打印调试信息的最佳解决方案。我编写了一个 DebugPrint 模块,有助于更轻松地使用记录器:

#DebugPrint.py
import logging
import os
import time

DEBUGMODE=True

logging.basicConfig(level=logging.DEBUG)
log=logging.getLogger('=>')    


#DebugPrint.py
#DbgPrint=logging.debug 
def DbgPrint(*args, **kwargs):
    if DEBUGMODE:
        #get module, class, function, linenumber information
        import inspect
        className = None
        try:
            className = inspect.stack()[2][0].f_locals['self'].__class__.__name__
        except:
            pass
        modName=None
        try:
            modName = os.path.basename(inspect.stack()[2][1])
        except:
            pass
        lineNo=inspect.stack()[2][2]
        fnName=None
        try:
            fnName = inspect.stack()[2][3]
        except:
            pass
        DbgText="line#{}:{}->{}->{}()".format(lineNo, modName,className, fnName)
        argCnt=len(args)
        kwargCnt=len(kwargs)
        #print("argCnt:{} kwargCnt:{}".format(argCnt,kwargCnt))
        fmt=""
        fmt1=DbgText+":"+time.strftime("%H:%M:%S")+"->"
        if argCnt > 0:
            fmt1+=(argCnt-1)*"%s,"
            fmt1+="%s"
            fmt+=fmt1

        if kwargCnt>0:
            fmt2="%s"
            args+=("{}".format(kwargs),)
            if len(fmt)>0:
                fmt+=","+fmt2
            else:
                fmt+=fmt2


        #print("fmt:{}".format(fmt))
        log.debug(fmt,*args)


if __name__=="__main__":
    def myTest():
        print("Running myTest()")
        DbgPrint("Hello","World")

myTest()
Run Code Online (Sandbox Code Playgroud)

如果 DEBUGMODE 变量为 false,则不会打印任何内容。
如果为真,上面的示例代码将打印出:

DEBUG:=>:16:24:14:line#78:DebugPrint.py->None->myTest():->Hello,World
Run Code Online (Sandbox Code Playgroud)

现在我将使用定义类的模块来测试 DebugPrint。

#testDebugPrint.py
from DebugPrint import DbgPrint


class myTestClass(object):
    def __init__(self):
        DbgPrint("Initializing the class")

    def doSomething(self, arg):
        DbgPrint("I'm doing something with {}".format(arg))

if __name__=='__main__':
    test=myTestClass()
    test.doSomething("a friend!")
Run Code Online (Sandbox Code Playgroud)

运行此脚本时,输出如下:

DEBUG:=>:16:25:02:line#7:testDebugPrint.py->myTestClass->__init__():->Initializing the class
DEBUG:=>:16:25:02:line#10:testDebugPrint.py->myTestClass->doSomething():->I'm doing something with a friend!
Run Code Online (Sandbox Code Playgroud)

请注意,控制台上打印的模块名称、类名称、函数名称和行号以及打印语句的时间都是正确的。

我希望您会发现这个实用程序很有用。