Шрифт:
'EXTENDED_ARG']
Легко догадаться, что LOAD означает загрузку значения в стек, STORE — выгрузку, PRINT — печать, BINARY — бинарную операцию и т.п.
Отладка
В интерпретаторе языка Python заложены возможности отладки программ, а в стандартной поставке имеется простейший отладчик — pdb. Следующий пример показывает программу, которая подвергается отладке, и типичную сессию отладки:
Листинг
# File myfun.py
def fun(s):
lst = []
for i in s:
lst.append(ord(i))
return lst
Так может выглядеть типичный процесс отладки:
Листинг
>>> import pdb, myfun
>>> pdb.runcall(myfun.fun, «ABCDE»)
> /examples/myfun.py(4)fun
— > lst = []
(Pdb) n
> /examples/myfun.py(5)fun
— > for i in s:
(Pdb) n
> /examples/myfun.py(6)fun
— > lst.append(ord(i))
(Pdb) l
1 #!/usr/bin/python
2 # File myfun.py
3 def fun(s):
4 lst = []
5 for i in s:
6 -> lst.append(ord(i))
7 return lst
[EOF]
(Pdb) p lst
[]
(Pdb) p vars
{'i': 'A', 's': 'ABCDE', 'lst': []}
(Pdb) n
> /examples/myfun.py(5)fun
— > for i in s:
(Pdb) p vars
{'i': 'A', 's': 'ABCDE', 'lst': [65]}
(Pdb) n
> /examples/myfun.py(6)fun
— > lst.append(ord(i))
(Pdb) n
> /examples/myfun.py(5)fun
— > for i in s:
(Pdb) p vars
{'i': 'B', 's': 'ABCDE', 'lst': [65, 66]}
(Pdb) r
— Return - > /examples/myfun.py(7)fun — >[65, 66, 67, 68, 69]
— > return lst
(Pdb) n
[65, 66, 67, 68, 69]
>>>
Интерактивный отладчик вызывается функцией pdb.runcall и на его приглашение (Pdb) следует вводить команды. В данном примере сессии отладки были использованы некоторые из следующих команд: l (печать фрагмент трассируемого кода), n (выполнить все до следующей строки), s (сделать следующий шаг, возможно, углубившись в вызов метода или функции), p (печать значения), r (выполнить все до возврата из текущей функции).
Разумеется, некоторые интерактивные оболочки разработчика для Python предоставляют функции отладчика. Кроме того, отладку достаточно легко организовать, поставив в ключевых местах программы, операторы print для вывода интересующих параметров. Обычно этого достаточно, чтобы локализовать проблему. В CGI–сценариях можно использовать модуль cgitb, о котором говорилось в одной из предыдущих лекций.
Профайлер
Для определения мест в программе, на выполнение которых уходит значительная часть времени, обычно применяется профайлер.
Модуль profile
Этот модуль позволяет проанализировать работу функции и выдать статистику использования процессорного времени на выполнение той или иной части алгоритма.
В качестве примера можно рассмотреть профилирование функции для поиска строк из списка, наиболее похожих на данную. Для того чтобы качественно профилировать функцию difflib.get_close_matches, нужен большой объем данных. В файле russian.txt собрано 160 тысяч слов русского языка. Следующая программа поможет профилировать функцию difflib.get_close_matches:
Листинг
import difflib, profile
def print_close_matches(word):
print "\n».join(difflib.get_close_matches(word + "\n», open(«russian.txt»)))
profile.run(r'print_close_matches(«профайлер»)')
При запуске этой программы будет выдано примерно следующее:
Листинг
провайдер
трайлер
бройлер
899769 function calls (877642 primitive calls) in 23.620 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 23.610 23.610 <string>:1(?)
1 0.000 0.000 23.610 23.610 T.py:6(print_close_matches)
1 0.000 0.000 0.000 0.000 difflib.py:147(__init__)
1 0.000 0.000 0.000 0.000 difflib.py:210(set_seqs)
159443 1.420 0.000 1.420 0.000 difflib.py:222(set_seq1)
2 0.000 0.000 0.000 0.000 difflib.py:248(set_seq2)
2 0.000 0.000 0.000 0.000 difflib.py:293(__chain_b)