调试(debugging)是一个解决代码中错误或导致软件不能正常运行的问题的过程。Python中的调试非常容易。Python调试器设置条件断点并对源码逐行调试。我们将使用Python标准库中的 pdb 模块来对我们的Python脚本进行调试。
为更好的调试Python程序,可以使用不同的技术。我们就来看看Python调试的四种技术:
在这一部分中我们将学习Python如何处理异常。但首先什么是异常呢?异常是在程序执行过程中发生的错误。每当错误发生时,Python会生成一个异常,使用try…except代码块来进行处理。有时异常程序无法处理,因此会导致报错信息。下面我们就来看一些异常的示例:
在你的终端中,启动python3交互控制台,我们一起来看一些异常示例:
>>> 50 / 0
Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: division by zero
>>> 6 + abc*5
Traceback (most recent call last):
File "", line 1, in
NameError: name 'abc' is not defined
>>> 'abc' + 2
Traceback (most recent call last):
File "", line 1, in
TypeError: Can't convert 'int' object to str implicitly
>>> import abcd
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named 'abcd'
这就是异常的一些示例。下面我们来看如何处理这些异常。
每当Python程序中发生错误时,就会抛出异常。我们也可使用raise关键字来强制抛出异常。
下来我们来看一个处理异常的try…except代码块。在try代码块中,我们将编写可能生成异常的代码。在except代码块中,我们将编写异常的处理方式。try…except的语法如下:
try:
statement(s)
except:
statement(s)
一个try代码块可带有多个except语句。我们可通过在except关键字之后输入异常的名称来处理指定的异常。处理指定异常的语法如下:
try:
statement(s)
except exception_name:
statement(s)
下面我们创建一个exception_example.py脚本来捕获ZeroDivisionError。在脚本中编写如下代码:
a = 35
b = 37
try:
c = a +b
print("The value of c is:", c)
d = b / 0
print("The value of d is:", d)
except:
print("Division by zero is not possible")
print("Out of try...except block")
像下面这样运行脚本,将会得到如下结果:
vagrant@python-scripting:~$ python3 exception_example.py
The value of c is: 72
Division by zero is not possible
Out of try...except block
Python中支持很多种调试工具:
这一部分中,我们将学习pdb Python调试器。pdb是Python标准库的一部分并一直可以直接使用。
pdb模块用于调试Python程序。Python程序使用pdb交互源代码调试器来调试程序。pdb设置断点并检查栈帧,列出源代码。
下面我们将学习如何使用pdb调试器。使用这一调试器有三种方式:
class Student:
def __init__(self, std):
self.count = std
def print_std(self):
for i in range(self.count):
print(i)
return
if __name__ == "__main__":
Student(5).print_std()
使用这一脚本作为学习Python调试的示例,我们将了解如何启动调试器的细节。
要从Python交互控制台中启动调试器,我们使用run()或runeval()。
启动python3交互控制台。运行如下命令来启动控制台:
$ python3
导入我们的pdb_example脚本名和pdb模块。下面我们将使用run(),并且我们会传入一个字符串表达式来作为run()的参数,由Python解释器自身进行运行:
>>> import pdb_example
>>> import pdb
>>> pdb.run('pdb_example.Student(5).print_std()')
> (1)()
(Pdb)
要继续调试,在(Pdb)提示符之后输入continue并按下Enter(或直接输入 h并回车)。我果想要了解这里可以使用的选项,在(Pdb)提示符之后按下两次Tab键。
在输入continue之后,我们将得到如下的输出:
>>> import pdb_example
>>> import pdb
>>> pdb.run('pdb_example.Student(5).print_std()')
> (1)()
(Pdb)
运行调试器最简单也最直接的方式是通过命令行。我们的程序将作为调试器的输入。我们可以这样在命令行中使用调试器:
$ python3 -m pdb pdb_example.py
有很多方式来让Python程序运行得更快,比如:
在本章中,我们学习了调试程序和性能分析的重要性。还学习了用于调试的不同技术。我们学习了pdb Python调试器以及如何处理异常。还学习了如何使用Python中的cProfile和timeit模块来对脚本进行性能和时耗分析。最后我们学习了如何加速脚本的运行。
下一章中,我们将学习Python中的单元测试。我们会学习如何创建和使用单元测试。
☞☞☞ 第三章-单元测试-单元测试框架的介绍
下表转自菜鸟教程:
变量名 | 描述 |
---|---|
PYTHONPATH | PYTHONPATH是Python搜索路径,默认我们import的模块都会从PYTHONPATH里面寻找。 |
PYTHONSTARTUP | Python启动后,先寻找PYTHONSTARTUP环境变量,然后执行此变量指定的文件中的代码。 |
PYTHONCASEOK | 加入PYTHONCASEOK的环境变量, 就会使python导入模块的时候不区分大小写. |
PYTHONHOME | 另一种模块搜索路径。它通常内嵌于的PYTHONSTARTUP或PYTHONPATH目录中,使得两个模块库更容易切换。 |
以下内容转自百度百科:
全局解释器锁(Global Interpreter Lock)是计算机程序设计语言解释器用于同步线程的工具,使得在同一进程内任何时刻仅有一个线程在执行。常见例子有CPython(JPython不使用GIL)与Ruby MRI。
详情
- Python的线程是操作系统线程。在Linux上为pthread,在Windows上为Win thread,完全由操作系统调度线程的执行。一个python解释器进程内有一条主线程,以及多条用户程序的执行线程。即使在多核CPU平台上,由于GIL的存在,所以禁止多线程的并行执行。
- Python解释器进程内的多线程是合作多任务方式执行。当一个线程遇到I/O任务时,将释放GIL。计算密集型(CPU-bound)的线程在执行大约100次解释器的计步(ticks)时,将释放GIL。计步(ticks)可粗略看作Python虚拟机的指令。计步实际上与时间片长度无关。可以通过sys.setcheckinterval()设置计步长度。
- 在单核CPU上,数百次的间隔检查才会导致一次线程切换。在多核CPU上,存在严重的线程颠簸(thrashing)。
- Python 3.2开始使用新的GIL。
- 可以创建独立的进程来实现并行化。