The content of this article is about debugging and analysis of Python scripts (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Debugging and profiling play an important role in Python development. Debuggers help programmers analyze complete code. The debugger sets breakpoints while the profiler runs our code and provides us with details of execution times. The profiler will identify bottlenecks in the program.
Debugging is the process of troubleshooting problems that arise in the code and prevent the software from functioning properly. In Python, debugging is very simple. The Python debugger sets conditional breakpoints and debugs source code one line at a time. We will use the pdb module from the Python standard library to debug our Python scripts.
In order to better debug Python programs, various techniques can be used. We will discuss four techniques for Python debugging:
In this section, we will learn how Python handles exceptions. Exceptions are errors that occur during program execution. Whenever any error occurs, Python will generate an exception, which will be handled using a try...except block. The program cannot handle certain exceptions, thus causing an error message. Now we'll see some unusual examples.
In the terminal, start the python3 interactive console and we will see some examples of exceptions:
student@ubuntu:~$ python3 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> 50 / 0 Traceback (most recent call last): File "", line 1, in ZeropisionError: pision 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' >>>
These are some examples of exceptions. Now we will see how we handle exceptions.
Whenever an error occurs in a Python program, an exception is thrown. We can also use the raise keyword to force an exception to be raised.
Now we will see a try...except block to handle exceptions. In the try block, we will write code that may generate exceptions. In the except block we will write the solution for this exception.
The syntax try...except is as follows:
try: statement(s) except: statement(s)
A try block can have multiple except statements. We can also handle specific exceptions by entering the exception name after the except keyword. The syntax for handling a specific exception is as follows:
try: statement(s) except exception_name: statement(s)
We will create an exception_example.py script to catch ZeropisionError. Write the following code in the script:
a = 35 b = 57 try: c = a + b print("The value of c is: ", c) d = b / 0 print("The value of d is: ", d) except: print("pision by zero is not possible") print("Out of try...except block")
Run the script as shown below and you will get the following output:
student@ubuntu:~$ python3 exception_example.py The value of c is: 92 pision by zero is not possible Out of try...except block
Python supports many debugging tools:
In this section, we will learn about the pdb Python debugger. pdbmodule is part of the Python standard library and is always available for use.
The pdb module is used to debug Python programs. Python programs use the pdb interactive source code debugger to debug programs. pdb sets breakpoints and inspects stack frames, and lists source code.
Now we will learn how to use the pdb debugger. There are three ways to use this debugger:
·In the interpreter
·From the command line
·In a Python script
We will create A pdb_example.py script and add the following content in the script:
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()
Taking this script as an example to learn Python debugging, we will see how to start the debugger in detail.
To start the debugger from the Python interactive console, we use run() or runeval().
Start the python3 interactive console. Run the following command to start the console:
$ python3
Import our pdb_example script name and pdb module. Now, we will use run() and we pass the string expression as argument to run() The Python interpreter itself:
student@ubuntu:~$ python3 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> import pdb_example >>> import pdb >>> pdb.run('pdb_example.Student(5).print_std()') > (1)() (Pdb)
To continue debugging, enter continue after the (Pdb) prompt and press Enter key. If you want to know the options we can use here, then press the Tab key twice after the (Pdb) prompt.
Now, after typing continue, we will get the following output:
student@ubuntu:~$ python3 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> import pdb_example >>> import pdb >>> pdb.run('pdb_example.Student(5).print_std()') > (1)() (Pdb) continue 0 1 2 3 4 >>>
The method is from the command line. Our program will serve as input to the debugger. You can use the debugger from the command line as follows:
$ python3 -m pdb pdb_example.py
When you run the debugger from the command line, the source code is loaded and it stops execution at the first line found. Enter continue to continue debugging. Here is the output:
student@ubuntu:~$ python3 -m pdb pdb_example.py > /home/student/pdb_example.py(1)() -> class Student: (Pdb) continue 0 1 2 3 4 The program finished and will be restarted > /home/student/pdb_example.py(1)() -> class Student: (Pdb)
The first two techniques will launch the debugger at the beginning of the Python program. But this third technique is best suited for long-running processes. To start the debugger in a script, use set_trace().
Now, modify your pdb_example.py file as follows:
import pdb class Student: def __init__(self, std): self.count = std def print_std(self): for i in range(self.count): pdb.set_trace() print(i) return if __name__ == '__main__': Student(5).print_std()
现在,按如下方式运行程序:
student@ubuntu:~$ python3 pdb_example.py > /home/student/pdb_example.py(10)print_std() -> print(i) (Pdb) continue 0 > /home/student/pdb_example.py(9)print_std() -> pdb.set_trace() (Pdb)
set_trace() 是一个Python函数,因此您可以在程序中的任何位置调用它。
因此,这些是启动调试器的三种方式。
在本节中,我们将看到跟踪模块。跟踪模块有助于跟踪程序执行。因此,每当您的Python程序崩溃时,我们都可以理解崩溃的位置。我们可以通过将跟踪模块导入您的脚本以及命令行来使用它。
现在,我们将创建一个名为脚本trace_example.py并在脚本中编写以下内容:
class Student: def __init__(self, std): self.count = std def go(self): for i in range(self.count): print(i) return if __name__ == '__main__': Student(5).go()
输出如下:
student@ubuntu:~$ python3 -m trace --trace trace_example.py --- modulename: trace_example, funcname: trace_example.py(1): class Student: --- modulename: trace_example, funcname: Student trace_example.py(1): class Student: trace_example.py(2): def __init__(self, std): trace_example.py(5): def go(self): trace_example.py(10): if __name__ == '__main__': trace_example.py(11): Student(5).go() --- modulename: trace_example, funcname: init trace_example.py(3): self.count = std --- modulename: trace_example, funcname: go trace_example.py(6): for i in range(self.count): trace_example.py(7): print(i) 0 trace_example.py(6): for i in range(self.count): trace_example.py(7): print(i) 1 trace_example.py(6): for i in range(self.count): trace_example.py(7): print(i) 2 trace_example.py(6): for i in range(self.count): trace_example.py(7): print(i) 3 trace_example.py(6): for i in range(self.count): trace_example.py(7): print(i) 4
因此,通过trace --trace在命令行使用,开发人员可以逐行跟踪程序。因此,只要程序崩溃,开发人员就会知道崩溃的实例。
分析Python程序意味着测量程序的执行时间。它衡量每个功能所花费的时间。Python的cProfile模块用于分析Python程序。
如前所述,分析意味着测量程序的执行时间。我们将使用cProfile Python模块来分析程序。
现在,我们将编写一个 cprof_example.py 脚本并在其中编写以下代码:
mul_value = 0 def mul_numbers( num1, num2 ): mul_value = num1 * num2; print ("Local Value: ", mul_value) return mul_value mul_numbers( 58, 77 ) print ("Global Value: ", mul_value)
运行程序,您将看到如下输出:
student@ubuntu:~$ python3 -m cProfile cprof_example.py Local Value: 4466 Global Value: 0 6 function calls in 0.000 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 cprof_example.py:1() 1 0.000 0.000 0.000 0.000 cprof_example.py:2(mul_numbers) 1 0.000 0.000 0.000 0.000 {built-in method builtins.exec} 2 0.000 0.000 0.000 0.000 {built-in method builtins.print} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
因此,使用时cProfile,所有被调用的函数都将打印出每个函数所花费的时间。现在,我们将看到这些列标题的含义:
· ncalls: 通话次数
· tottime: 在给定函数中花费的总时间
· percall:商数tottime除以ncalls
· cumtime:在此和所有方面花费的累计时间 subfunctions
· percall:cumtime除以原始调用的商数
· filename:lineno(function):提供每个功能的相应数据
timeit是一个Python模块,用于计算Python脚本的一小部分。您可以从命令行调用timeit,也可以将timeit模块导入到脚本中。我们将编写一个脚本来计算一段代码。创建一个timeit_example.py脚本并将以下内容写入其中:
import timeit prg_setup = "from math import sqrt" prg_code = ''' def timeit_example(): list1 = [] for x in range(50): list1.append(sqrt(x)) ''' # timeit statement print(timeit.timeit(setup = prg_setup, stmt = prg_code, number = 10000))
使用timeit,我们可以决定我们要测量的代码片段。因此,我们可以轻松定义设置代码以及我们要单独执行测试的代码段。主代码运行100万次,这是默认时间,而设置代码只运行一次。
有多种方法可以使Python程序运行得更快,例如:
The above is the detailed content of Debugging and analysis of Python scripts (code examples). For more information, please follow other related articles on the PHP Chinese website!