Home  >  Article  >  Backend Development  >  Debugging and analysis of Python scripts (code examples)

Debugging and analysis of Python scripts (code examples)

不言
不言forward
2019-04-11 13:08:353895browse

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.

Python Debugging Technology

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:

  • print() Statement: This is the easiest way to understand what is going on, so you can inspect what was executed.
  • logging: This is like a print statement, but with more contextual information so you can fully understand it.
  • pdb debugger: This is a commonly used debugging technique. The advantage of using pdb is that you can use pdb from the command line, interpreter and program.
  • IDE Debugger: The IDE has an integrated debugger. It allows developers to execute their code, who can then inspect the program as it executes.

Error Handling (Exception Handling)

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

Debugger Tool

Python supports many debugging tools:

  • winpdb
  • pydev
  • pydb
  • pdb
  • gdb
  • pyDebug

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.

pdb debugger

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.

In the interpreter

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 easiest and most straightforward way to run the debugger from the command line

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)

In a Python script

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模块

如前所述,分析意味着测量程序的执行时间。我们将使用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

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程序运行得更快,例如:

  • 描述您的代码,以便识别瓶颈
  • 使用内置函数和库,因此解释器不需要执行循环
  • 避免使用全局变量,因为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!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete