Рабочий процесс отладки
Вы должны понимать, что на самом деле вы используете другую интеграцию отладчика Python pdb
и ipdb
(который использует pdb
, к которому можно получить доступ с помощью модуля ipdb
). Надеюсь, этот тривиальный пример поможет вам лучше его использовать.
Предположим, вы хотите отладить этот код:
def Waiting_fun(): #1 line number one
for i in range(100): #2
pass #3
#4
def New_sum(lista, to_s = False): #5
result = 0 #6
print 1 #7
for i in lista: #8
print "summed" #9
result +=i #10
Waiting_fun() #11
if to_s: #12
result = str(result)
return result
a = New_sum([1,4,5,7,8])
b = New_sum([1,4],1)
c = 456
d = New_sum([6,8,9],1)
final_result = a*b*c*d
Out: Type error
Быстрая первая отладка с использованием iPython% debug
%debug
Первое, что я делаю, это вызываю pdb из iPython с помощью волшебной команды %debug
, вы можете установить ее как механизм по умолчанию, используя %pdb
.
%debug
> /home/opdate/Desktop/test.py(23)<module>()
19 a = New_sum([1,4,5,7,8])
20 b = New_sum([1,4],1)
21 c = 456
22 d = New_sum([6,8,9],1)
---> 23 final_result = a*b*c*d
После обеда pdb
. Вы можете найти все команды в официальных документах или использовать команду h
для покажите их. На этом этапе я использую только следующие команды:
p
: печатает указанные вами переменные
pp
: красивые принты
args
: если вы находитесь внутри функции, она печатает аргументы
pp locals()
: может быть полезно распечатать все переменные, но в большинстве случаев это беспорядок!
!
используйте его, если хотите избежать конфликтов с командами, перечисленными в h
whatis
имя_переменной: эквивалент типа (имя_переменной)
u
: переместить текущий кадр на один уровень вверх в трассировке стека (к более старому кадру).
d
: переместить текущий кадр на один уровень вниз в трассировке стека (к более новому кадру).
q
: когда вы закончите, вы можете использовать q для выхода
В нашем случае:
ipdb> pp a,b,c,d
(25, '5', 456, '23')
Или ipdb> !a,b,c,d
(без пробела между знаком эскламации и первым значением). Понятно, что b и d - это строки, если мы можем использовать:
ipdb> whatis b
<type 'str'>
Углубляемся с помощью точек останова
В 70% случаев %debug
указывает вам на решение. Когда вам нужно больше функций, таких как точки останова, пора использовать Spyder. В этом случае мы хотим понять, почему b
- это строка, рядом с которой мы ставим точку останова (двойной щелчок рядом с номером строки в окне редактора). Я считаю, гораздо лучше использовать для отладки стандартную консоль Python вместо консоли IPython, поэтому выберите консоль перед началом отладки: ![введите описание изображения здесь]( https://i.stack.imgur.com/yDvfP.png )
Затем откройте variable explorer
, если есть какие-то переменные, удалите их. Я использую Ctrl + F5, чтобы начать отладку, вы можете использовать кнопки вверху, но я предпочитаю использовать их сочетания клавиш, показанные ниже:
![введите описание изображения здесь](https://i.stack.imgur.com/CwQAF.png)
(Pdb) c # we go to the breakpoint
(Pdb) s # we step into the function
(Pdb) args # we see what parameters are inserted
(Pdb) s # going step-by-step
(Pdb) ⏎ # series of Enters go line by line quicker
#Here I'll use whatis command but in fact I just look to
# the type in variable explorer of spyder.
(Pdb) whatis result #check if result is still int
(Pdb) unt #or until -useful to exiting from loops see doc.
(Pdb) n # we don't enter to the Waiting_fun function
(Pdb) s # going step-by-step
(Pdb) whatis result #we find that there the int is converted
(Pdb) j 6 # for double checking we jump back to 6 were the result is assigned
# We may be tempted to j(ump) to line 12 but doing so we would skip all the code
#for avoiding a series of `s`,`unt` and `n` we can use this solution:
(Pdb) tbreak 12 #set a new temporary breakpoint. Also `b` it's ok most of the time
(Pdb) c # go to it
(Pdb) j 6 # we jump to 6 the code we jump is NOT executed
(Pdb) whatis result# we find that if we jump 12-13 result is still int
Теперь мы нашли ошибку. Мы также можем протестировать решение, повторяем шаг до 12 и устанавливаем to_s = False
(Pdb) to_s = False #!to_s = False to be on the safe side
Оно работает. Одной из важных особенностей использования стандартного pdb в консоли Python является то, что у вас есть автоконкурс, и вы можете использовать проводник переменных вместо использования whatis
и pp
:
![введите описание изображения здесь](https://i.stack.imgur.com/0IVHU.png)
Используя проводник переменных, вы также можете изменить значения переменных, что сделает работу еще быстрее.
Условные точки останова
Еще один более умный способ найти ошибку - использовать условную точку останова (Shift + F12). Большое преимущество Spyder заключается в отладке и использовании список точек останова. Условные точки останова активируются, когда условие равно True
. В нашем случае мы хотим определить, где b становится строкой, поэтому условие будет: type(b) == str
. Обычно я помещаю много условных точек останова и смотрю, какие из них соответствуют условию. Для этого не используйте Shift + F12, а поместите обычные точки останова, дважды щелкнув рядом со строкой, и перейдите в раздел «Отладка-› Список точек останова », скопируйте и вставьте условие в таблицу к каждой точке останова, как показано на рисунке ниже.
![введите описание изображения здесь](https://i.stack.imgur.com/gLIeA.png)
Отсюда следует использовать следующие команды:
(Pdb) c # go to the first
(Pdb) u # it helps to understand when it happened
(Pdb) d # come back to the breakpoint
person
G M
schedule
01.12.2017
sys.exit()
, но было бы удобнее, если бы у меня была опция точки останова. - person wick   schedule 02.04.2018