Heim  >  Artikel  >  Backend-Entwicklung  >  Debuggen und Analysieren von Python-Skripten (Codebeispiele)

Debuggen und Analysieren von Python-Skripten (Codebeispiele)

不言
不言nach vorne
2019-04-11 13:08:353921Durchsuche

Der Inhalt dieses Artikels befasst sich mit dem Debuggen und Analysieren von Python-Skripten (Codebeispiele). Ich hoffe, dass er für Freunde hilfreich ist.

Debugging und Profiling spielen eine wichtige Rolle in der Python-Entwicklung. Debugger helfen Programmierern bei der Analyse des vollständigen Codes. Der Debugger setzt Haltepunkte, während der Profiler unseren Code ausführt und uns Details zur Ausführungszeit liefert, identifiziert der Profiler Engpässe im Programm.

Python-Debugging-Technologie

Debuggen ist der Prozess der Lösung von Problemen, die im Code auftreten und verhindern, dass die Software ordnungsgemäß funktioniert. In Python ist das Debuggen sehr einfach. Der Python-Debugger setzt bedingte Haltepunkte und debuggt den Quellcode Zeile für Zeile. Wir werden das pdb-Modul aus der Python-Standardbibliothek verwenden, um unsere Python-Skripte zu debuggen.

Um Python-Programme besser debuggen zu können, können verschiedene Techniken eingesetzt werden. Wir werden vier Techniken zum Python-Debuggen besprechen:

  • print()-Anweisung: Dies ist der einfachste Weg, zu verstehen, was vor sich geht, sodass Sie überprüfen können, was ausgeführt wurde.
  • Protokollierung: Dies ist wie eine gedruckte Aussage, jedoch mit mehr Kontextinformationen, damit Sie sie vollständig verstehen können.
  • PDB-Debugger: Dies ist eine häufig verwendete Debugging-Technik. Der Vorteil der Verwendung von pdb besteht darin, dass Sie pdb über die Befehlszeile, den Interpreter und das Programm verwenden können.
  • IDE-Debugger: Die IDE verfügt über einen integrierten Debugger. Es ermöglicht Entwicklern, ihren Code auszuführen, der dann das Programm während der Ausführung überprüfen kann.

Fehlerbehandlung (Ausnahmebehandlung)

In diesem Abschnitt erfahren Sie, wie Python mit Ausnahmen umgeht. Ausnahmen sind Fehler, die während der Programmausführung auftreten. Immer wenn ein Fehler auftritt, generiert Python eine Ausnahme, die mithilfe eines try...exclusive-Blocks behandelt wird. Das Programm kann bestimmte Ausnahmen nicht verarbeiten, was zu Fehlermeldungen führt. Jetzt sehen wir einige ungewöhnliche Beispiele.

Starten Sie im Terminal die interaktive Python3-Konsole und wir sehen einige Beispiele für Ausnahmen:

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'
>>>

Dies sind einige Beispiele für Ausnahmen. Jetzt werden wir sehen, wie wir mit Ausnahmen umgehen.

Immer wenn in einem Python-Programm ein Fehler auftritt, wird eine Ausnahme ausgelöst. Wir können auch das Schlüsselwort raise verwenden, um das Auslösen einer Ausnahme zu erzwingen.

Jetzt sehen wir einen try...except-Block, der Ausnahmen behandelt. Im try-Block schreiben wir Code, der Ausnahmen generieren kann. Im Except-Block schreiben wir die Lösung für die Ausnahme.

Die Syntax try...exclusive lautet wie folgt:

try:
            statement(s)
except:
            statement(s)

Ein try-Block kann mehrere Except-Anweisungen haben. Wir können auch bestimmte Ausnahmen behandeln, indem wir den Ausnahmenamen nach dem Schlüsselwort „exclusive“ eingeben. Die Syntax zur Behandlung einer bestimmten Ausnahme lautet wie folgt:

try:
            statement(s)
except exception_name:
            statement(s)

Wir erstellen ein Skript „Exception_example.py“, um ZeropisionError abzufangen. Schreiben Sie den folgenden Code in das Skript:

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")

Führen Sie das Skript wie unten gezeigt aus und Sie erhalten die folgende Ausgabe:

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 unterstützt viele Debugging-Tools:

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

In diesem Abschnitt erfahren Sie mehr über den pdb-Python-Debugger. pdbmodule ist Teil der Python-Standardbibliothek und steht jederzeit zur Verwendung zur Verfügung.

pdb-Debugger

Das pdb-Modul wird zum Debuggen von Python-Programmen verwendet. Python-Programme verwenden zum Debuggen von Programmen den interaktiven Quellcode-Debugger pdb. pdb setzt Haltepunkte, prüft Stapelrahmen und listet den Quellcode auf.

Jetzt lernen wir, wie man den PDB-Debugger verwendet. Es gibt drei Möglichkeiten, diesen Debugger zu verwenden:

· Im Interpreter

· Über die Befehlszeile

· In einem Python-Skript

Wir erstellen Ein pdb_example.py-Skript und fügen Sie den folgenden Inhalt in dieses Skript ein:

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()

Anhand dieses Skripts als Beispiel zum Erlernen des Python-Debuggens werden wir sehen, wie der Debugger im Detail gestartet wird.

Im Interpreter

Um den Debugger von der interaktiven Python-Konsole aus zu starten, verwenden wir run() oder runeval().

Starten Sie die interaktive Python3-Konsole. Führen Sie den folgenden Befehl aus, um die Konsole zu starten:

$ python3

Importieren Sie unseren pdb_example-Skriptnamen und unser pdb-Modul. Jetzt verwenden wir run() und übergeben den String-Ausdruck als Argument an run(). Der Python-Interpreter selbst:

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)

Um mit dem Debuggen fortzufahren, geben Sie nach der (Pdb)-Eingabeaufforderung continue ein und drücken Sie die Eingabetaste. Wenn Sie wissen möchten, welche Optionen wir hier verwenden können, drücken Sie nach der Eingabeaufforderung (Pdb) zweimal die Tabulatortaste.

Nachdem wir nun continue eingegeben haben, erhalten wir die folgende Ausgabe:

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

Die einfachste und unkomplizierteste Möglichkeit, den Debugger über die Befehlszeile auszuführen

Die Methode erfolgt über die Befehlszeile. Unser Programm dient als Eingabe für den Debugger. Sie können den Debugger wie folgt über die Befehlszeile verwenden:

$ python3 -m pdb pdb_example.py

Wenn Sie den Debugger über die Befehlszeile ausführen, wird der Quellcode geladen und die Ausführung wird bei der ersten gefundenen Zeile gestoppt. Geben Sie continue ein, um mit dem Debuggen fortzufahren. Hier ist die Ausgabe:

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 einem Python-Skript

Die ersten beiden Techniken starten den Debugger am Anfang des Python-Programms. Diese dritte Technik eignet sich jedoch am besten für lang laufende Prozesse. Um den Debugger in einem Skript zu starten, verwenden Sie set_trace().

Ändern Sie nun Ihre pdb_example.py-Datei wie folgt:

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在访问全局变量时非常慢
  • 使用现有包

Das obige ist der detaillierte Inhalt vonDebuggen und Analysieren von Python-Skripten (Codebeispiele). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen