Як ефективно налагодити шпигунську програму в 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.