Як ефективно налагодити шпигунську програму в Python?


75

Мені подобається Python і мені подобається Spyder, але налагодження за допомогою Spyder мені здається жахливим!

  • Кожного разу, коли я ставлю точку зупинки, мені потрібно натискати дві кнопки: спочатку налагоджувальну, а потім кнопку продовження (вона автоматично робиться на першому рядку), що дратує.
  • Більше того, замість того, щоб мати стандартну консоль iPython з автоматичним заповненням тощо, у мене паскудна консоль ipdb >>, яка є просто сміттям.
  • Найгірше те, що ця консоль дуже часто зависає, навіть якщо я пишу відбитки або просту оцінку, щоб спробувати зрозуміти, в чому помилка. Це набагато гірше, ніж матлаб.
  • І останнє, але не менш важливе: якщо я викликаю функцію з консолі ipdb >> і вкладу в неї точку зупинки, вона на цьому не зупиниться. Здається, я повинен помістити там точку зупинки, перш ніж розпочати налагодження (ctrl + F5).

У вас є рішення, чи, можливо, ви можете сказати мені, як ви налагоджуєте сценарії та функції python?

Я використовую свіжу інсталяцію Anaconda на Windows 8.1 64bit.


Не стосується складної налагодження, але мені часто доводиться зупинятися посередині сценарію, щоб використовувати певний набір змінних для подальшого розвитку в консолі. Зазвичай я просто ввожу sys.exit()тимчасово, але було б зручніше, якби у мене була можливість зупинки.
— фітиль

Відповіді:


54

( Тут розробник Spyder ) Ми усвідомлюємо, що досвід налагодження у Spyder далеко не ідеальний. Те, що ми пропонуємо зараз, дуже схоже на стандартний налагоджувач Python, але ми працюємо над вдосконаленням речей у нашій наступній великій версії, щоб надати щось ближче до того, що будь-який вчений очікував би від налагоджувача (коротше кажучи, звичайна консоль IPython, яка дозволяє ви перевіряєте і складаєте змінні в поточній точці зупинки).

Тепер про ваші моменти:

  1. Це правда. Ми думаємо вдосконалити це так, щоб, якщо користувач натискає кнопку Виконати, і в поточному файлі присутня точка зупинки, тоді Spyder переходить у режим налагодження та виконує програму доти, доки не буде досягнуто першу точку зупинки.

  2. ipdb- це консоль налагоджувача IPython. На жаль, через обмеження в архітектурі IPython він дуже обмежений (відсутність заповнення коду та перегляд історії зі стрілками). Крім того, неможливо запустити довільний код Python ні в одній, ipdbні в звичайній pdbконсолі. Команди, в яких ви можете запускатись, ipdb- це ті, які ви можете прочитати при оцінці helpкоманди всередині неї.

  3. Це тому, що, як я вже сказав, ви не можете оцінити довільний код Python.

  4. Вам потрібно вставити нові точки зупинки в наш редактор, щоб вони синхронізувалися з нашими консолями Python / IPython


13
Я хотів би вказати на ще одну особливість, яку я вважаю важливою. В даний час налагодження можливе лише за допомогою "Файлу налагодження", який запускає файл від початку до кінця в окремому сеансі, забуваючи всі змінні, які я міг визначити в консолі. Було б чудово, щоб мати можливість розпочати налагодження певної функції, передаючи їй змінні, вже визначені в моєму робочому просторі (які іноді дорого перераховуються)
— Лев

1
@neuronet, це вже працює, але лише за умови натискання кнопки налагодження (тобто синьої кнопки відтворення / паузи).
— Carlos Cordoba

2
@neuronet, будь ласка, відкрийте питання про це, щоб краще зрозуміти, що відбувається у вашому випадку.
— Карлос Кордова,

2
@CarlosCordoba добре зробить, не поспішаючи намагатись не робити нічого дурного. :)
— eric

1
@CarlosCordoba Я думаю, що я начебто змусив це працювати. Мені довелося переконатись, що в усьому файлі немає помилок, і натиснути кнопку відтворення / паузи (оскільки такі речі, як ctrl-F12, нічого не робили, поки я не перейшов у режим налагодження за допомогою ctrl-F5). Тепер, коли я це бачу, я можу дослідити це більше, але також набагато краще оціню тут OP та вашу відповідь. Matlab просто так добре справляється з цим, це вимагає від мене звикання ... Якась чітка документація також пройшла б тут дуже великий шлях, зокрема для відновлення користувачів Matlab, які очікують, що Spyder буде «схожий на Matlab».
— eric

27

Процес налагодження

Ви повинні розуміти, що насправді ви використовуєте різну інтеграцію налагоджувача Pythonpdb і 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

Перше, що я роблю, це викликати 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 для налагодження, тому виберіть консоль перед початком налагодження: введіть тут опис зображення

Потім відкрийте, variable explorerякщо є якісь змінні, видаліть їх. Я використовую Ctrl+ F5для запуску налагодження, ви можете використовувати кнопки вгорі, але я волію використовувати їх ярлики, показані нижче:

введіть тут опис зображення

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

введіть тут опис зображення

Використовуючи провідник змінних, ви також можете змінити значення змінних, що робить справи ще швидшими.

Умовні точки зупинку

Ще одним розумним способом виявити помилку є використання умовної точки зупинку ( Shift+ F12), великою перевагою Spyder є налагодження та використання точок зупинки списку. Умовні точки зупину активується , коли умова TrueВ нашому випадку, ми хочемо , щоб визначити , де б стає рядком , тому умова: type(b) == str. Зазвичай я розміщую багато умовних точок зупинку і бачу, які відповідають умові. Для цього не використовуйте Shift+, F12а двічі клацніть поруч із рядком звичайні точки зупинки та перейдіть до Налагодження-> Список точок зупинки та скопіюйте та перенесіть умову в таблиці до кожної точки зупинку, як показано на малюнку нижче.

введіть тут опис зображення

Звідси команди, які слід використовувати:

(Pdb) c  # go to the first
(Pdb) u # it helps to understand when it happened
(Pdb) d # come back to the breakpoint

4

Налагоджувач pdb чудово працює із звичайним python . Тому в Spyder я просто переходжу на консоль python, коли хочу інтерактивно налагоджувати.

import pdb

def yourfunction():
    # Interesting stuff done here
    pdb.set_trace() 

Хороший вступ до налагодження за допомогою pdb https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/


1
На жаль:NOTE: The Python console is going to be REMOVED in Spyder 3.2. Please start to migrate your work to the IPython console instead.
— C8H10N4O2 01.03.18

1

Ось як я налагоджую в Spyder, щоб уникнути заморожування IDE. Я роблю це, якщо я зміню сценарій у режимі налагодження.

  1. Я закриваю поточну консоль IPython (налагодження) [x]
  2. Відкрийте новий [Рядок меню-> Консолі-> Відкрити консоль IPython]
  3. Знову увійдіть у режим налагодження [синя кнопка паузи відтворення].

Все ще трохи дратує, але це має додаткову перевагу очищення (скидання) списку змінних.


1

Ніхто раніше ніколи не згадував про цих двох:

До Python я використовував VBA. Хоча це відносно стара мова, яка регулярно не оновлюється, одна річ, яка мені сподобалась у VBA, - це функція налагодження. Дві функції налагодження, які є найближчими до VBA або які також можна назвати "візуальною налагодженням", з якими я стикався:

1-PyCharm налагоджувач

Це 6-хвилинне відео демонструє налагоджувач PyCharm.

2-PixieDebugger - Візуальний налагоджувач Python для ноутбуків Jupyter, якого ви завжди хотіли

Оскільки багато кодерів, як правило, використовують JupyterNotebook, цей налагоджувач стане в нагоді. PixieDebugger - це майже те саме, що і налагоджувач PyCharm. Я не буду вдаватися тут докладно.

Але ви можете посилатися на це посилання


2
Питання про Spyder, і жоден із згаданих вами налагоджувачів не може бути використаний у Spyder.
— Carlos Cordoba

1
Я це знаю. Я просто виділяв різні типи візуальних налагоджувачів python. Не обов’язково для шпигуна.
— mcagriardic

0

Одна незначна додаткова інформація щодо пункту 3:

Мені також здавалося, що консоль налагодження часто зависає, виконуючи відбитки, оцінюючи тощо, але натискання кнопки зупинки (Вихід з налагодження) зазвичай повертає її до нижньої частини стека викликів, і тоді я можу повернутися вгору ('u') до кадру, в якому я налагоджував. Варто спробувати. Це може бути для пізнішої версії Spyder (2.3.5.2)


0

Ви можете використовувати комбінації клавіш для налагодження, такі як: Крок через F10 Крок у F11 в інструментах> налаштування> комбінації клавіш

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.