当前位置: 首页 > 科技观察

还在使用print()语句调试Python代码?停止

时间:2023-03-20 15:15:39 科技观察

使用print()的缺点我是那些使用print()语句来调试代码的人之一。有的时候,如果代码很长,那么印刷就会比较多,需要用多个符号来相互区分。看看下面的代码片段。(本博客中的代码片段,跟随Python3.7的语言)print(style_dict,"{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]")#Addingintoadictionaryres_dct={style_dict[i]:style_dict[i+1]foriinrange(0,len(style_dict),2)}res_dist={res_dct['EmailAddress']:{style_dict[i]:style_dict[i+1]foriinrange(0,len(style_dict),2)}}print(res_dist,"+++++++++++++++++++++++++++++++++++++++++++++++++++++")recon_dict=res_dctprint(recon_dict,"----------------------------------------------")#RemovingspacesothatdatacanbetransferredtoHTMLfieldsrecon_dict={x.translate({32:None}):yforx,yinlist(recon_dict.items())}print("##################################################")print(recon_dict)print("################################################")#ConvertingtoJSONr=json.dumps(recon_dict)print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")print(r)loaded_json=json.loads(r)print("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwwwwww")print("***********************************************************")print(loaded_json)在这里我试图将字典添加到JSON文件由于一些错误我不得不使用这么多带有不同符号的打印语句进行调试。但是作为代码变大,不同的模块,不同的类调用其他模块或类中的不同定义,这不是一个好的选择。让我们看看这种方法的一些缺点:随着代码的增长,很难在??每个模块,类中使用打印语句,或代码遍历的定义。代码执行并在我们注意到错误之前进入下一步。等到冗长的执行完成后再找到并修复它。返回通过巨大的日志搜索会很乏味我们在print语句中给出的正确符号并匹配它们。一个简单的转换,我们不需要做任何事情,只需使用“pdb模块”,这是Python为我们提供的强大武器。这个Modules帮助我们有效地调试。什么是pdb(python调试器)?pdb是一个交互式shell,有助于调试python代码。它帮助我们逐步进入代码,暂停,检查状态并继续下一行代码或继续执行。调用pdb的一些方法:这里,我们将介绍三种调用pdb的方法。事后分析:如果你想在程序层面调试,请使用这个函数。inlinepdb:适用于3.7版本之前的版本breakpoint():对于3.7或之后的版本事后我们用一个简单的程序来理解。defadd_num(listA,num):sum=[]foriinlistA:sum.append(i*num)returnsumlistA=[2,4,6,8]num=10result=add_num(listA,num)print(result)这里defadd_num要把num变量的值加到名为listA的列表中的每个元素上,把新值存入列表总和,并返回列表总和。通过执行如下所示的python文件,将调用pdb,python-mpdbdebug_add.py这将进入pdb模式并在第一行代码处停止。(venv)C:\Users\PycharmProjects\>python-mpdbdebug_add.py>c:\users\pycharmprojects\debug_add.py(2)()->defadd_num(listA,num):(Pdb)任何时候,如果您需要有关调试器的帮助,请使用列出所有选项的“h”(帮助)。(Pdb)hDocumentedcommands(typehelp):==========================================EOFcdhlistqrvundisplayacldebughelpllquitsuntaliascleardisableignorelonglistrsourceuntilargscommandsdisplayinteractnrestartstepupbconditiondownjnextreturntbreakwbreakcontenablejumppretvaluwhatisbtcontinueexitlpprununaliaswhereMiscellaneoushelptopics:==========================execpdb对特定选项的帮助,(Pdb)hdebugdebugcodeEnterarecursivedebuggerthatstepsthroughthecodeargument(whichisanarbitraryexpressionorstatementtobeexecutedinthecurrentenvironment).返回程序,使用选择项'n'(next)进入下一步执行。>c:\users\pycharmprojects\debug_add.py(2)<模块>()->defadd_num(listA,num):(Pdb)n>c:\users\prade\pycharmprojects\jobportal\debug_add.py(8)()->listA=[2,4,6,8]在这里我们可以通过这样给变量名来检查变量的值,(Pdb)listA***NameError:name'listA'isnotdefined(Pdb)***NameError:name'listA'isnotdefined我们到达行listA=[2,4,6,8]但我们仍然没有执行它,所以它说listA未定义。如果你观察到我们在任何时候按下回车键,前面的选项都会像上面那样执行。现在按“n”向前移动并检查listA变量。(Pdb)n>c:\users\pycharmprojects\debug_add.py(9)()->num=10(Pdb)listA[2,4,6,8](Pdb)来检查我们的代码在行中,使用选项“l”(行)。箭头标记指向我们所在的行,EOF表示文件结束。(Pdb)l4foriinlistA:5sum.append(i*num)6returnsum78listA=[2,4,6,8]9->num=1010result=add_num(listA,num)11print(result)[EOF](Pdb)退出调试,我们使用选项“q”(退出)。(pdb)q(venv)C:\Users\PycharmProjects\>另一种使用postmortem方法的方法是只在遇到异常时才停止执行,因为使用-ccontinuewith-mpdbpython-mpdb-ccontinuedebug_add.pyBreakpoint()从Python3.7开始,引入了breakpoint(),这有助于调试Python代码,而无需显式导入模块pdb并调用pdb.set_trace()。breakpoint()为我们完成所有这些并在控制台中打开PDB调试器。现在,让我们在没有任何断点的情况下执行上面的代码,如果遇到错误则进行调试。defadd_num(listA,num):sum=[]foriinlistA:sum.append(i*num)returnsumlistA=[2,4,6,8]num=10result=add_num(listA,num)print(result)输出:C:\Users\PycharmProjects\venv\Scripts\python.exeC:/Users/PycharmProjects/debug_add.py[20,40,60,80]Processfinishedwithexitcode0代码块的任务是将num(10)添加到list,并返回新列表。预期结果是[12,14,16,18]实际结果是[20,40,60,80]现在让我们使用breakpoint()武器来调试和修复代码。在哪里放置断点()取决于怀疑错误的地方。在这种情况下,我们将它放在它进入add_num()定义之前。defadd_num(listA,num):sum=[]foriinlistA:sum.append(i*num)返回sumlistA=[2,4,6,8]num=10breakpoint()result=add_num(listA,num)print(result)输出:>c:\users\pycharmprojects\debug_add.py(11)<模块>()->result=add_num(listA,num)(Pdb)n>c:\users\pycharmprojects\debug_add.py(12)()->print(result)(Pdb)n[20,40,60,80]—返回—>c:\users\prade\pycharmprojects\jobportal\debug_add.py(12)()->None->print(result)(Pdb)选项“n”(下一个)用于移动到下一行或单步执行任何定义。但在这种情况下,我们需要进入定义,为此我们将使用选项“s”(步骤)。下面的粗体文本用于突出显示使用的选项及其解释。>c:\users\prade\pycharmprojects\jobportal\debug_add.py(11)()->result=add_num(listA,num)(Pdb)s<-----Stepintodefadd_num--调用-->c:\users\prade\pycharmprojects\jobportal\debug_add.py(2)add_num()->defadd_num(listA,num):(Pdb)s<----steppedinsidedefadd_num>c:\users\prade\pycharmprojects\jobportal\debug_add.py(3)add_num()->sum=[](Pdb)n<---insideadeffeelfreetouse'n'>c:\users\prade\pycharmprojects\jobportal\debug_add.py(4)add_num()->foriinlistA:(Pdb)n>c:\users\prade\pycharmprojects\jobportal\debug_add.py(5)add_num()->sum.append(i*num)(Pdb)n>c:\users\prade\pycharmprojects\jobportal\debug_add.py(4)add_num()->foriinlistA:(Pdb)sum<--examinesumvalue[20]<--2+10=12not20,oopsweused'*'insteadof'+'inappendingtolistsum,小心!(Pdb)i<--so,examinei2(Pdb)sum.append(i+num)<--tryadding+intheexpression(Pdb)sum[20,12]<--PERFECT,FIXEDIT!(Pdb)u<--用于跳过循环的迭代。>c:\users\prade\pycharmprojects\jobportal\debug_add.py(11)<模块>()->result=add_num(listA,num)(Pdb)c<--usedtocontinuewithexecution[20,12,40,60,80]<--notarightanswerbutfoundafix.步骤,检查此时“i”是否为2,然后尝试sum.append(i+num)。然后检查总和并得到12这是最近添加的元素。所以我们得到了修复,所以我们使用选项“u”(直到)跳过for循环的剩余迭代。然后它在循环后移动到下一步。这里我们用'c'(continue)继续执行,结果就结束了。现在修复,defadd_num(listA,num):sum=[]foriinlistA:sum.append(i+num)returnsumlistA=[2,4,6,8]num=10result=add_num(listA,num)print(result)output:C:\Users\PycharmProjects\venv\Scripts\python.exeC:/Users/PycharmProjects/debug_add.py[12,14,16,18]Processfinishedwithexitcode0没有乱七八糟的print()语句,这看起来很简单。