1.7 Python技巧
除了Python的基本语法和调用API,程序的调试方法也很重要。本节将集中介绍Python调试及异常处理的一些技巧。
1.7.1 Python程序调试
1.命令行调试工具pdb
从一个简单例程开始,编写Python程序a.py如下:
用pdb命令调试程序:
2.常用pdb命令
最常用的命令如下:
◎ 单步调试(进入函数):s(tep)。
◎ 单步调试(不进入函数):n(ext)。
◎ 继续往后执行,直到下个断点:c(ont(inue))。
◎ 运行到函数结束:r(eturn)。
◎ 运行到当前循环结束:unt(il)。
◎ 设置断点:b(reak)文件名:行号(或行号,或函数名)。
◎ 显示当前调用关系:w(here)。
◎ 显示当前代码段:l(ist)。
◎ 显示变量:p(rint)变量名。
◎ 显示当前函数的参数:a(rgs)。
◎ 显示帮助信息:h(elp)。
◎ 退出:q(uit)。
可以看到,pdb命令的使用方法与C语言的调试工具gdb类似。
3.在代码中设置断点
在使用Jupyter Notebook进行开发时,常把功能分块写入Cell分别调试,以实现调试代码段的功能。在需要进入函数内部调试或者单步运行时,可以直接在程序中设置断点,其方法是在要设置断点的代码前输入:
当程序运行到此处时就出现了pdb的命令行,此时可以输入上方的pdb命令进行单步调试,也可以在输入框中运行Python语句。以上方法在命令行也可以使用。
4.在程序出错时调出pdb
在Jupyter中加入魔法命令“%pdb”即可在程序出错时调用pdb,以便调试出错时的具体代码。
1.7.2 去掉警告信息
在Python的输出中,有时会在有效输出的信息中出现一些警告信息(warning),使用以下方法可去掉警告信息输出。
1.7.3 制作和导入模块
当一个Python程序过于庞大时,往往需要将其拆分成多个程序文件“.py”,有时被多个程序调用的公共函数也单独作为“.py”文件,在使用时它们要被其他程序导入。在Python中,每个“.py”文件都可以作为模块在其他程序中用import导入。
当被导入文件和使用它的文件在同一目录中时,直接通过文件名即可导入。当模块文件较多时,有时也将多个“.py”文件放在一个目录中,即生成包Package,包的目录下必须包含名为__init__.py的文件。如果没有该文件,该目录就不会被识别为Package。
1.制作模块
下面用例程的方式展示导入同一目录及子目录中的模块。首先建立如下的目录结构,在第一层目录中main.py为调用其他模块的主程序;a.py为被导入的模块a;tools为一子目录,其中包含被导入的模块b.py;__init__.py是Package的标识。
然后在程序a.py中定义函数A:
在程序b.py中定义函数B:
在程序main.py中分别导入模块a和包tools中的模块b:
2.设置模块路径
Python支持导入三种模块:系统模块、三方模块、自定义模块。当自定义的模块和包在当前目录下时,直接使用import导入即可;当模块在Python定义的第三方库目录下(如“/usr/local/lib/python3.7/site-packages/”)时,也可以直接导入,大多数第三方模块都以该方式导入。对于自定义模块,可通过添加系统模块路径“sys.path”的方式加入新的模块或包所在路径,以便当前程序正常加载该库,具体方法如下:
3.重新加载模块
当一个模块被import导入多次时,只有第一次加载其内容,其后再导入则加载内存中的内容。在使用Jupyter调试程序时,如果调用程序main.py和a.py模块同步调试,有时修改了a.py模块内容后就需要重新加载,此时可使用reload方法,具体如下:
1.7.4 异常处理
当程序运行出错时会抛出异常,如果不做处理则程序会异常退出。Python也支持用try/except方式捕获异常,其语法规则如下:
简单实例如下:以读取方式打开文件test.txt,当该文件不存在时将抛出异常,如例程中捕获异常并显示具体的异常信息。从返回结果可以看到,在捕捉到异常信息后,程序正常执行了之后的打印信息操作。