>-> 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
> 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)
> 324261 2.240 0.000 2.240 0.000 difflib.py:32(_calculate_ratio)