Крок за крокам адладкі з IPython

З таго, што я прачытаў, ёсць два спосабу адладкі кода ў Python:

  • З дапамогай традыцыйнага адладчыка, такія як PDB або IPDB . Гэта падтрымлівае каманды, такія як C для Працягнуць , п для ступеністым над , S </код > для крок у і г.д.), але не маюць прамога доступу да абалонцы IPython, якая можа быць надзвычай карысным для абследавання аб'екта.

  • <�Літый> <�р> Выкарыстанне <�моцны> IPython </моцны> па ўкладання ў абалонку IPython ў вашым кодзе. Вы можаце зрабіць з IPython імпарту ўстаўляць , а затым выкарыстоўваць ўбудоўваць() у кодзе. Калі ваша праграма/скрыпт дзівіць ўбудавання() заяву, вы ўпалі ў абалонку IPython. Гэта дазваляе поўнае абследаванне аб'ектаў і тэставанне кода Python, выкарыстоўваючы ўсе прысмакі IPython. Аднак, пры выкарыстанні ўбудаванні() вы не можаце <�моцны> крок за крокам з дапамогай кода больш з зручных спалучэнняў клавіш.

Ці ёсць спосаб аб'яднаць лепшае з абодвух сьветаў? гэта значыць

  1. Умець <�моцны> крок за крокам праз код з зручным PDB/IPDB спалучэння клавіш.
  2. <�Літый> У любой такой стадыі (напрыклад, на дадзеным заяве), маюць доступ да паўнавартаснай <�моцнай> IPython абалонкі </моцнай>.

IPython адладкі , як у MATLAB:

Прыклад такога тыпу «пашыраная адладка» можна знайсці ў MATLAB, дзе карыстальнік <�моцны> заўсёды мае поўны доступ да MATLAB рухавік/абалонцы, і яна ўсё яшчэ можа <�моцнага> крок за крокам праз яе код, вызначыць ўмоўныя кропкі супыну і г.д. з таго, што я абмяркоўваў з іншымі карыстальнікамі, гэта функцыя адладкі, што людзі выпускаюць самы пры пераходзе ад MATLAB да IPython.

адладкі IPython ў Emacs і іншых рэдактараў:

Я не хачу, каб гэтае пытанне занадта спецыфічны, але я працую ў асноўным у Emacs, так што мне цікава, ці ёсць спосаб, каб давесці гэтую функцыянальнасць у яго. <�Моцны> У ідэале , Emacs (ці рэдактар) дазволіць праграмісту ўсталёўваць кантрольныя кропкі ў любым месцы кода і мець зносіны з перакладчыкам або адладчык, каб ён спыніцца ў месцы па вашаму выбару, і давесці да поўнай IPython перакладчык на гэтым месцы.

126
Дзякуй @ Клеман Я ішоў РЭПО на працягу апошняга месяца, і я вельмі рады аб праекце :) Я не спрабаваў яшчэ, але як толькі я (ці, калі вы робіце), не саромейцеся напісаць адказ тут, што можа быць паказвае, як выканаць тое, што патрабуецца. Для іншых для даведкі, URL з'яўляецца github.com/rocky/emacs-dbgr
дададзена аўтар Amelio Vazquez-Reina, крыніца
@ Клеман Акрамя таго, калі ў вас ёсць вопыт працы з RealGUD & IPDB, я паспрабаваў выкарыстаць яго, як і тут,
дададзена аўтар Amelio Vazquez-Reina, крыніца
Гэта выдатна, што вы адкрылі білет :) Выглядае як ваша праблема была вырашана, тоже ^^
дададзена аўтар Clément, крыніца
Для карыстальнікаў Emacs, RealGUD мае вельмі добры інтэрфейс.
дададзена аўтар Clément, крыніца
Я шукаю пітон адладчык, падобны на Matlab, таксама! Напрыклад, я шмат прототипирования ў абалонцы Python. Усе зменныя захоўваюцца з абалонкай. Зараз я сустракаюся з праблемай. Я спадзяюся, адладжваць адзін невялікі фрагмент кода, з разлічаным пераменным з абалонкай. Аднак, новы адладчык не можа атрымаць доступ да старых пераменным. Гэта не вельмі зручна для прототипирования.
дададзена аўтар user1914692, крыніца
PDB мае каманда, якая выконвае любую каманду пітона ў кантрольнай кропцы
дададзена аўтар Dmitry Galchinsky, крыніца

13 адказы

Як наконт ipdb.set_trace ()? У кодзе:

<�Код> імпарт IPDB; ipdb.set_trace()

Гэта дазваляе поўнае абследаванне вашага кода, і ў вас ёсць доступ да каманд, такіх як з (працягнуць), п (выканаць наступны радок), S </код > (крок у метад у кропцы) і гэтак далей.

Глядзіце IPDB РЭПО і спіс каманд . IPython цяпер называецца (рэдагаванне: частка) Jupyter .


пс: звярніце ўвагу, што IPDB каманда мае прыярытэт над пітонам кодам. Таму для таго, каб напісаць Спіс (Foo) вам патрэбен Спіс друку (Foo) .

Акрамя таго, калі вам падабаецца IPython запрашэнне (яго Emacs і рэжымы Вім, гісторыя, дапрацовак, ...) лёгка атрымаць тое ж самае для вашага праекта, паколькі ён заснаваны на Python запрашэнне інструментар .

79
дададзена
Мой адказ цяпер ўключае ў сябе, як выкарыстоўваць IPDB у Emacs, выкарыстоўваючы RealGUD і isend рэжым , каб рабіць тое, што просіць ОП.
дададзена аўтар Amelio Vazquez-Reina, крыніца
Гэта спосаб зрабіць гэта.
дададзена аўтар j08lue, крыніца
Jupyter не з'яўляецца заменай для IPython, але IPython наўтбукаў. Jupyter ноўтбукі выкарыстоўваюць ядро ​​ў фонавым рэжыме. Для ноўтбука Python, ядро ​​звычайна ядро ​​IPython. праект IPython працягвае далей.
дададзена аўтар revers, крыніца

(Абнаўленне ад 28 мая 2016 г.) Выкарыстанне RealGUD ў Emacs

Для тых, хто ў Emacs, гэтай тэме паказана, як выканаць усе апісанае ў ОП ( і больш), выкарыстоўваючы

  1. новы важны адладчык ў Emacs называецца <�моцны> RealGUD , які можа працаваць з любым адладчыкам (у тым ліку IPDB ).
  2. Пакет Emacs isend рэжым .

Спалучэнне гэтых двух пакетаў з'яўляецца надзвычай магутным і дазваляе ўзнавіць менавіта паводзіны, апісанае ў OP і зрабіць яшчэ больш.

Больш падрабязная інфармацыя аб вікі артыкулы ў RealGUD для IPDB.


Арыгінальны адказ:

Пасля таго, як перакаштаваў шмат розных метадаў для адладкі Python, уключаючы ўсе згаданыя ў гэтай тэме, адзін з маіх пераважных спосабаў адладкі Python з IPython з'яўляецца з убудаванымі ракавінамі.

Вызначэнне карыстацкіх ўбудаванай абалонкі IPython:

Дадайце наступны код на скрыпт у ваш PYTHONPATH , так што метад ipsh() становіцца даступным.

import inspect

# First import the embed function
from IPython.terminal.embed import InteractiveShellEmbed
from IPython.config.loader import Config

# Configure the prompt so that I know I am in a nested (embedded) shell
cfg = Config()
prompt_config = cfg.PromptManager
prompt_config.in_template = 'N.In <\\#>: '
prompt_config.in2_template = '   .\\D.: '
prompt_config.out_template = 'N.Out<\\#>: '

# Messages displayed when I drop into and exit the shell.
banner_msg = ("\n**Nested Interpreter:\n"
"Hit Ctrl-D to exit interpreter and continue program.\n"
"Note that if you use %kill_embedded, you can fully deactivate\n"
"This embedded instance so it will never turn on again")   
exit_msg = '**Leaving Nested interpreter'

# Wrap it in a function that gives me more context:
def ipsh():
    ipshell = InteractiveShellEmbed(config=cfg, banner1=banner_msg, exit_msg=exit_msg)

    frame = inspect.currentframe().f_back
    msg   = 'Stopped at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)

    # Go back one level! 
    # This is needed because the call to ipshell is inside the function ipsh()
    ipshell(msg,stack_depth=2)

Затым, калі я хачу адладзіць нешта ў маім кодзе, я змяшчаю ipsh() прама ў тым месцы, дзе мне трэба зрабіць агляд аб'екта і г.д. Напрыклад, сказаць, што я хачу, каб адладзіць my_function ніжэй

З яго дапамогай:

def my_function(b):
  a = b
  ipsh() # <- This will embed a full-fledged IPython interpreter
  a = 4

а затым я выклікаю My_function (2) ў адным з наступных спосабаў:

  1. Альбо запусціўшы праграму на Python, які выклікае гэтую функцыю з Unix абалонкі
  2. Ці запусціўшы яго непасрэдна з IPython

Незалежна ад таго, як я выклікаю яго, інтэрпрэтатар спыняецца на радку, якая кажа ipsh() . Пасля таго, як вы скончыце, вы можаце зрабіць Ctrl-D і Python адновіць выкананне (з любымі зменнымі абнаўленнямі, якія вы зрабілі). Звярніце ўвагу, што, калі вы запусціце код з звычайнай IPython абалонкі IPython (выпадак 2 вышэй), новы IPython абалонка будзе <�моцнага> укладзенай ўнутры аднаго з якіх вы яго выклікалі, што цалкам нармальна, але гэта добра, каб быць у курсе. Eitherway, калі інтэрпрэтатар спыняецца на месцазнаходжанні ipsh , я магу праверыць значэнне а (які будзе 2 ), убачыць, што функцыі і аб'екты вызначаны і г.д.

Праблема:

Рашэнне вышэй, можа быць выкарыстана, каб Python спыніць ў любым месцы вы хочаце ў вашым кодзе, а затым высадзіць вас у паўнавартасны інтэрпрэтатар IPython. На жаль, гэта не дазваляе дадаваць або выдаляць кропкі супыну, як толькі вы выклікаеце сцэнар, які вельмі складана. На мой погляд, гэта <�моцны> толькі рэч, якая перашкаджае IPython стаць выдатным інструментам адладкі для Python.

Лепшае, што вы можаце зрабіць зараз:

Абыйсці гэта месца ipsh() апрыёрна ў розных месцах, дзе патрабуецца інтэрпрэтатар Python для запуску абалонкі IPython (г.зн. кропкі супыну ). Затым вы можаце «скакаць» паміж рознымі загадзя вызначанай, жорстка закадаваным «кантрольнымі кропкамі» з Ct-D </кодам>, які будзе выйсці з бягучага убудаванага абалонкі IPython і зноў спыняцца, калі інтэрпрэтатар патрапіць у наступны выклік < код> ipsh() .

Калі вы ідзяце па гэтым шляху, адзін са спосабаў выхаду з «рэжым адладкі» і ігнараваць ўсе наступныя кропкі супыну, каб выкарыстоўваць ipshell.dummy_mode = True , які прымусіць Python ігнараваць любыя наступныя асобнікі элемента аб'ект, які мы стварылі вышэй.

40
дададзена
@Phani - так, вы можаце зрабіць гэта ў любы час падчас «сеансу адладкі» (гэта значыць кожны раз, калі укладзеная абалонка ipsh() выклікаецца, і вы зрабілі з адладкай).
дададзена аўтар Amelio Vazquez-Reina, крыніца
Дзякуючы @tuner Гэта правільна. Я усталяваў яе ў сваім адказе.
дададзена аўтар Amelio Vazquez-Reina, крыніца
@LucasAlonso я была такой жа праблемай, з убудаванымі ракавінамі. Я думаю, што ёсць некаторыя квіткі аб гэтай праблеме ў IPython (Дарэчы, убачыць маё апошняе абнаўленне на гэты адказ).
дададзена аўтар Amelio Vazquez-Reina, крыніца
@luator Я думаю, што розніца ў тым, што гэты метад дазваляе выкарыстоўваць IPython права на кантрольнай кропцы і выканаць любую каманду Python. <�Код> ipdb.set_trace толькі дае доступ да IPDB Каманды
дададзена аўтар Berk U., крыніца
Мне трэба дадаць імпарт аглядайце , перш чым ён працаваў. Камандны радок налады, здаецца, зламаная, хоць для мяне.
дададзена аўтар Pascal, крыніца
але ён кажа, што ён не можа знайсці ipshell пераменнага.
дададзена аўтар Phani, крыніца
дзе мы выкарыстоўваем ipshell.dummy_mode = True ? Ці можам мы выкарыстоўваць яго з з у бягучай сесіі IPython?
дададзена аўтар Phani, крыніца
Калі ласка, абновіце гэта кожны раз, калі вы знойдзеце яшчэ лепшае рашэнне. Але гэта выглядае выдатна. Я буду выкарыстоўваць яго.
дададзена аўтар Phani, крыніца
Чаму б не толькі з дапамогай імпарт IPDB; ipdb.set_trace() ? Можа быць, я нешта прапусціў, але я не бачу перавага вашай значна больш складаным спосабам.
дададзена аўтар luator, крыніца
@BerkU. I <�я> можна </я> выканаць любую каманду Python з ipdb.set_trace . Прынамсі, я не заўважыў якіх-небудзь абмежаванняў, і я выкарыстоўваю яго даволі шмат.
дададзена аўтар luator, крыніца
Дзе/як вы вызначаеце/імпарту CFG, banner_msg, exit_msg, і праверыць?
дададзена аўтар Gordon Bean, крыніца
@GordonBean я знайшоў кантэкст ў іншым адказе: stackoverflow.com/questions/15669186/…
дададзена аўтар karan.dodia, крыніца
Гэта, здаецца, працуе добра для мяне: github.com/kdodia/snippets/blob/ вядучы/ipsh.py
дададзена аўтар karan.dodia, крыніца
Пры выкарыстанні гэтага метаду і запісаць гэты код: а = 3; Каўпачок = [а для й у дыяпазоне (1)] інтэрпрэтатар выводзіць: NameError: Імя 'а' не вызначана . Я паняцця не маю, чаму.
дададзена аўтар Lucas Alonso, крыніца

Вы можаце пачаць IPython сесію pudb і вярнуцца да сесіі адладкі, як вам падабаецца.

Дарэчы, IPDB выкарыстоўвае IPython за кулісамі, і вы можаце выкарыстоўваць функцыянальныя магчымасці IPython, такія як завяршэнне TAB і магічных каманд (адна пачынаецца з % ). Калі ўсё ў парадку з IPDB вы можаце запусціць яго з IPython, выкарыстоўваючы каманды, такія як % прабег і % адладкі . IPDB сесія на самай справе лепш, чым просты IPython у тым сэнсе, вы можаце пайсці ўверх і ўніз ў трасіроўку стэка і г.д. Што адсутнічае ў IPDB для «агляду аб'екта»?

Also, python.el bundled with Emacs >= 24.3 has nice ipdb support.

18
дададзена
Дзякуючы ТКФ. Я вялікі прыхільнік вашага пакета Emacs-джэдая. Калі вы сказалі, што Emacs 24,3 мае добрую падтрымку IPDB, вы не пярэчыце распрацоўкі? Я звычайна пачынаю IPython ў асобным Мх ANSI-тэрмін буфера, а затым я выкарыстоўваю isend рэжым , каб звязаць свае зыходныя буферы ў буфер IPython, так што я магу адправіць код інтэрпрэтатара IPython з дапамогай спалучэння клавіш, якая аўтаматычна пасылае % пасты магія ў буфер IPython. Гэта дазваляе мне хутка праверыць рэгіёны IPython. Я заўсёды запускаць мае праграмы з гэтай абалонкі IPython з Выканаць і выкарыстоўвайце ўбудоўваць() , каб спыніць.
дададзена аўтар Amelio Vazquez-Reina, крыніца
Дзякуючы @tkf Як я магу пачаць IPDB сеанс адладкі, выкарыстоўваючы python.el і ёсць такія рэчы, як адпраўка ў вобласць і г.д. ў адпаведнай абалонцы? Увогуле, дзе я магу знайсці больш інфармацыі па гэтым пытанні?
дададзена аўтар Amelio Vazquez-Reina, крыніца
Напрыклад, пры выкананні кода, зыходны код адкрыты ў іншым буферы з стрэлкай, якая паказвае бягучую кропку выканання. У вас таксама ёсць каманда адправіць-вобласць, як вы робіце з isend-рэжыме.
дададзена аўтар tkf, крыніца
Я выкарыстоўваю % прабег або % адладкі . Я мяркую, што імпарт IPDB; ipdb.set_trace() таксама працуе. Я не думаю, што вы можаце адправіць некалькі радкоў у IPDB. Гэта абмежаванне IPDB ст. Але, верагодна, % паста трук працуе. Вы можаце адправіць запыт на вылучэнне ў IPython распрацоўніка.
дададзена аўтар tkf, крыніца

Ніхто не згадаў IPython ў % PDB сцяг яшчэ. Проста выклічце % PDB у IPython і пры памылкі, вы аўтаматычна зваліўся да IPDB . Пакуль вы не непасрэдна ступаючы, вы ў IPDB пасля гэтага.

Гэта робіць адладку асобных функцый лёгка, як вы можаце проста загрузіць файл з кодам <>% нагрузкі , а затым запусціць функцыю. Вы маглі б прымусіць памылку з кодам <> сцвярджаюць у правільным становішчы.

12
дададзена
^ Гэта рэальны адказ
дададзена аўтар Cesar, крыніца
Ці ёсць нешта падобнае, дзе PDB мае IPython як функцыянальнасць, не будучы ў IPython першапачаткова?
дададзена аўтар Lucas, крыніца

Падобна на тое, падыход в @ gaborous адказваюць асуджаецца .

Новы падыход, здаецца:

from IPython.core import debugger
debug = debugger.Pdb().set_trace

def buggy_method():
    debug()
8
дададзена
Ці значыць гэта дазволіць вам выкарыстоўваць IPDB аператары ўнутры IPython абалонкі, пры адладцы?
дададзена аўтар alpha_989, крыніца

Прыстаўка «!» сімвал каманды, якія вы ўводзіце ў PDB, здаецца, мае той жа эфект, што робіць нешта ў абалонцы IPython. Гэта працуе для доступу да дапамогі для пэўнай функцыі, ці нават імёнаў зменных. Можа быць, гэта дапаможа вам у некаторай ступені. Напрыклад,

ipdb> help(numpy.transpose)
*** No help on (numpy.transpose)

Але! Дапамога (numpy.transpose) дасць вам чаканую старонку даведкі па numpy.transpose. Аналагічна для імёнаў зменных, скажам, у вас ёсць пераменная л, набраўшы «л» у PDB спісаў код, але! Л друкуе значэнне л.

6
дададзена
Гэта непрыемны PDB Гоча, а таксама варта ведаць.
дададзена аўтар Wilfred Hughes, крыніца

Спрабавалі Ці вы гэтага наканечніка ?

<�Р> Ці яшчэ лепш, выкарыстоўваць IPython і выклікаць: <�Папярэдне> з IPython.Debugger імпарту Tracer; debug_here = Tracer ()      <�Р>, то вы можаце проста выкарыстоўваць <�Папярэдне> debug_here ()      <�Р> кожны раз, калі вы хочаце ўсталяваць кропку супыну
4
дададзена

Адным з варыянтаў з'яўляецца выкарыстанне IDE, як Spyder , які дазволіць вам ўзаемадзейнічаць з вашым кодам падчас адладкі (выкарыстоўваючы IPython кансоль, на самай справе). На самай справе, Spyder вельмі MATLAB тыпу, які я мяркую, было наўмысным. Гэта ўключае ў сябе зменныя інспектар, зменную рэдагаванне, убудаваны доступ да дакументацыі і г.д.

3
дададзена

Калі вы набярэце выхад() у ўрэзаць() суцяшаць код працягнуць і перайсці да наступнага ўрэзаць лініі ().

2
дададзена

Pyzo IDE мае такія ж магчымасці, як прасілі ОП для. Вам не прыйдзецца пачынаць у рэжыме выпраўленьня. Аналагічна MATLAB, каманды выконваюцца ў абалонцы. Падчас усталявання брэйк-пойнт у нейкі зыходны код лініі, IDE спыняе выкананне, і вы можаце адладжваць і выдаваць рэгулярныя IPython каманды, а таксама.

Падобна на тое, аднак, што крок у ня (пакуль?) Добра працуе (гэта значыць прыпынак у адным радку, а затым ўступаюць у іншую функцыю), калі вы не задасце іншы брэйк-пойнт.

Тым не менш, зыходзячы з MATLAB, гэта, здаецца, лепшае рашэнне, якое я знайшоў.

2
дададзена
Гэта не працуе на Python 2.7 канчатковага ИЭП 3.7
дададзена аўтар Volodimir Kopey, крыніца

Запуск ўнутры Emacs 'IPython-абалонкі і кропкі супыну, усталяванай з дапамогай pdb.set_trace() павінен працаваць.

Праверана з пітона-mode.el, М-х IPython RET і г.д.

1
дададзена

З пітона 3.2, у вас ёсць ўзаемадзейнічае каманды, якая дае вам доступ да поўнага пітону/IPython каманднага прасторы.

1
дададзена

права, лёгкі, халодны, дакладны адказ на пытанне, каб выкарыстоўваць% макрас запусціць са сцягам -d.

In [4]: run -d myscript.py
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.        
> /cygdrive/c/Users/mycodefolder/myscript.py(4)()
      2                                                            
      3                        
----> 4 a=1                                            
      5 b=2
1
дададзена