IPython을 사용한 단계별 디버깅


170

내가 읽은 것에서 파이썬으로 코드를 디버깅하는 두 가지 방법이 있습니다.

  • 전통적인 디버거와 같은 pdbipdb. 등이 지원하는 명령 c에 대한 continue, n대한 step-over, s대한 step-into등),하지만 당신은 개체 검사에 매우 유용 할 수있는 IPython 쉘에 직접 액세스 할 수 없습니다.

  • 코드에 IPython 쉘 을 임베드 하여 IPython 사용 을 수행 한 다음 코드에서 사용할 수 있습니다. 프로그램 / 스크립트가 명령문에 도달하면 IPython 쉘에 빠지게됩니다. 이를 통해 모든 IPython 제품을 사용하여 객체를 완전히 검사하고 Python 코드를 테스트 할 수 있습니다. 그러나 사용 하면 편리한 키보드 단축키로 더 이상 코드를 단계별로 볼 수 없습니다 .from ipython import embedembed()embed()embed()

두 세계의 최고를 결합 할 수있는 방법이 있습니까? 즉

  1. 할 수있을 단계별로 편리 PDB / ipdb 키보드 단축키를 사용하여 코드를 통해.
  2. 그러한 단계에서 (예 : 주어진 문장에서) 본격적인 IPython 쉘에 액세스 할 수 있습니다 .

MATLAB 에서와 같은 IPython 디버깅 :

이 유형의 "향상된 디버깅"의 예는 MATLAB에서 찾을 수 있으며, 여기서 사용자는 항상 MATLAB 엔진 / 쉘에 대한 전체 액세스 권한을 가지고 있으며 여전히 단계별 코드, 조건부 중단 점 정의 등을 수행 할 수 있습니다. 다른 사용자와 논의한 내용은 MATLAB에서 IPython으로 이동할 때 사람들이 가장 놓치는 디버깅 기능입니다.

Emacs 및 기타 편집기에서 IPython 디버깅 :

질문을 너무 구체적으로 만들고 싶지는 않지만 대부분 Emacs에서 일하기 때문에이 기능을 가져올 수있는 방법이 있는지 궁금합니다. 이상적으로 는 Emacs (또는 에디터)는 프로그래머가 코드의 어느 곳에서든 중단 점을 설정하고 인터프리터 또는 디버거와 통신하여 선택한 위치에서 중지하고 해당 위치에서 완전한 IPython 인터프리터를 가져올 수 있도록합니다.


pdb에는 !중단 점에서 모든 파이썬 명령을 실행하는 명령이 있습니다.
Dmitry Galchinsky

5
Matlab과 비슷한 파이썬 디버거를 찾고 있습니다! 예를 들어, 파이썬 쉘에서 많은 프로토 타이핑을합니다. 모든 변수는 쉘과 함께 저장됩니다. 이제 문제가 발생합니다. 쉘을 사용하여 계산 된 변수를 사용하여 하나의 작은 코드 조각을 디버그하려고합니다. 그러나 새 디버거는 이전 변수에 액세스 할 수 없습니다. 프로토 타이핑에는 편리하지 않습니다.
user1914692 2016 년

1
Emacs 사용자에게는 RealGUD의 인터페이스가 매우 뛰어납니다.
Clément

1
@ Clément에게 감사드립니다. 지난 달에 리포지토리를 따라 왔으며 프로젝트에 대해 매우 기대하고 있습니다.) 요청한 것을 달성하는 방법을 보여줍니다. 참조를 위해 다른 사람을 위해, URL은 github.com/rocky/emacs-dbgr
아멜리오 바스케스 - 레이나

@ Clément 또한 RealGUD 및 ipdb에 대한 경험이 있으면 여기에 설명 된 대로 github.com/rocky/emacs-dbgr/issues/96 을 사용해 보았습니다 .
Amelio Vazquez-Reina

답변:


61

IPython의 %pdbmagic을 사용할 수 있습니다 . %pdbIPython에서 전화 하면 오류가 발생하면 자동으로 (으)로 이동 ipdb합니다. 당신은 즉시 스테핑을하지 않지만, 당신은 ipdb나중에 있습니다.

따라서 파일을로드 한 %load다음 함수를 실행할 수 있으므로 개별 함수를 쉽게 디버깅 할 수 있습니다 . assert올바른 위치에 오류가있을 수 있습니다.

%pdb라인 매직입니다. 로 전화 %pdb on, %pdb 1, %pdb off또는 %pdb 0. 인수없이 호출되면 토글로 작동합니다.


6
^ 이것은 정답입니다
Cesar

pdb가 초기에 IPython에 있지 않고 기능과 같은 IPython과 비슷한 점이 있습니까?
Lucas

4
ipython --pdb file.py -- args예외가 발생 하면 프로그램을 시작하여 ipdb로 드롭 할 수도 있습니다 . 답변에 추가 할 가치가 있습니다.
sebastian

110

ipdb.set_trace ()는 어떻습니까? 귀하의 코드에서 :

import ipdb; ipdb.set_trace()

업데이트 : 이제 Python 3.7에서 작성할 수 있습니다 breakpoint(). 동일하게 작동하지만 PYTHONBREAKPOINT환경 변수 도 준수 합니다. 이 기능은 이 PEP 에서 제공됩니다 .

이를 통해 코드를 완전히 검사 할 수 있으며 c(계속), n(다음 줄 실행), s(방법의 단계 ) 등의 명령에 액세스 할 수 있습니다 .

ipdb repo명령 목록을 참조하십시오 . IPython 은 이제 Jupyter 라고합니다 (편집 : 일부) .


추신 : ipdb 명령이 파이썬 코드보다 우선합니다. 따라서 글을 쓰 list(foo)려면 필요합니다 print list(foo).

또한 ipython 프롬프트 (emacs 및 vim 모드, 히스토리, 완료 등)가 마음에 들면 python prompt 툴킷을 기반으로하기 때문에 프로젝트에서 동일하게 쉽게 얻을 수 있습니다.


10
이것이 방법입니다.
j08lue

내 대답은 지금 사용하는 방법을 포함 ipdb하여 이맥스 RealGUDisend-mode영업 이익이 요청을 정확하게 할 수 있습니다.
Amelio Vazquez-Reina

1
Jupyter는 IPython 대신 IPython Notebook을 대체합니다. Jupyter 노트북은 백그라운드에서 커널을 사용합니다. Python 노트북의 경우 커널은 일반적으로 IPython 커널입니다. IPython 프로젝트는 더 계속됩니다.
FA

1
breakpoint()멋진. PyCharm에서는 심지어 PyCharm 디버거로 넘어갑니다. 콘솔에 붙여 넣은 함수에서 PyCharm 디버거를 빠르게 입력 할 수도 있습니다.
Richard Möhn

40

Emacs에서 RealGUD 사용 (2016 년 5 월 28 일 업데이트)

Emacs 사용자라면 누구나이 스레드 를 사용하여 OP (및 기타)에 설명 된 모든 것을 수행하는 방법을 보여줍니다

  1. Emacs의 RealGUD 라는 새로운 중요한 디버거 는를 포함하여 모든 디버거와 작동 할 수 있습니다 ipdb.
  2. 이맥스 패키지 isend-mode.

이 두 패키지의 조합은 매우 강력하며 OP에 설명 된 동작을 정확하게 재현하고 더 많은 작업을 수행 할 수 있습니다.

ipdb 용 RealGUD 위키 기사대한 추가 정보 .


원래 답변 :

이 스레드에서 언급 한 모든 것을 포함하여 Python을 디버깅하기위한 많은 다른 방법을 시도한 후에 IPython으로 Python을 디버깅하는 가장 좋은 방법 중 하나는 임베디드 쉘입니다.

사용자 정의 임베디드 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. Unix 쉘에서이 함수를 호출하는 Python 프로그램을 실행하여
  2. 또는 IPython에서 직접 호출하여

호출 방법에 관계없이 인터프리터는라는 줄에서 멈 춥니 다 ipsh(). 완료되면 할 수 Ctrl-D있고 파이썬은 변수 업데이트와 함께 실행을 재개합니다. 일반 IPython에서 IPython 셸 (위의 경우 2)에서 코드를 실행하면 새 IPython 셸이 사용자가 호출 한 것 안에 중첩 됩니다. 이는 완벽하지만 괜찮습니다. 어쨌든 통역사가의 위치에서 멈 추면 () ipsh의 값을 검사하고 정의 된 함수와 객체 등을 볼 수 있습니다.a2

문제 :

위의 솔루션을 사용하면 코드에서 원하는 곳에서 Python을 중지 한 다음 본격적인 IPython 인터프리터에 빠뜨릴 수 있습니다. 불행히도 스크립트를 호출하면 중단 점을 추가하거나 제거 할 수 없으므로 매우 실망 스럽습니다. 내 생각에 이것은 IPython이 Python을위한 훌륭한 디버깅 도구가되는 것을 방해 하는 유일한 것입니다.

지금 당신이 할 수있는 최선의 방법 :

해결 방법은 ipsh()Python 인터프리터가 IPython 셸을 시작하려는 다른 위치에 우선 순위를 지정 하는 것입니다 (예 : a breakpoint). 그런 다음로 미리 정의 된 하드 코딩 된 "브레이크 포인트"사이를 "점프" Ctrl-D하여 현재 내장 된 IPython 셸을 종료하고 인터프리터가 다음에 호출 할 때마다 다시 중지합니다 ipsh().

이 경로를 사용하면 "디버깅 모드"를 종료하고 이후의 모든 중단 점을 무시하는 한 가지 방법은 ipshell.dummy_mode = True파이썬이 ipshell위에서 만든 객체 의 후속 인스턴스화를 무시 하도록 하는 것 입니다.


2
더 나은 솔루션을 찾을 때마다 이것을 업데이트하십시오. 그러나 이것은 좋아 보인다. 사용하겠습니다.
Phani

1
cfg, banner_msg, exit_msg 및 inspect를 정의 / 가져 오는 위치 / 방법은 무엇입니까?
Gordon Bean

1
이것은 나를 위해 잘 작동하는 것 같다 : github.com/kdodia/snippets/blob/master/ipsh.py
karan.dodia

1
import inspect작동하기 전에 추가 해야했습니다. 커맨드 라인 커스터마이징이 나에게는 깨진 것 같습니다.
파스칼

7
왜 사용하지 import ipdb; ipdb.set_trace()않습니까? 어쩌면 나는 뭔가를 그리워하지만 훨씬 더 복잡한 방법의 이점을 보지 못합니다.
루이 터

19

pudb 에서 IPython 세션을 시작 하고 원하는대로 디버깅 세션으로 돌아갈 수 있습니다.

BTW, ipdb는 배후에서 IPython을 사용하고 있으며 실제로 TAB 완성 및 마술 명령 (시작은 %) 과 같은 IPython 기능을 사용할 수 있습니다 . ipdb에 문제가 없으면 %runand 같은 명령을 사용하여 IPython에서 시작할 수 있습니다 %debug. ipdb 세션은 실제로 스택 추적 등에서 위아래로 이동할 수 있다는 점에서 일반 IPython 세션보다 낫습니다. "객체 검사"를 위해 ipdb에서 무엇을 놓치고 있습니까?

또한 Emacs> = 24.3과 함께 번들로 제공되는 python.el은 훌륭한 ipdb를 지원합니다.


1
감사합니다 tkf. 저는 Emacs-Jedi 패키지의 팬입니다. Emacs 24.3이 ipdb를 훌륭하게 지원한다고 말했을 때 좀 더 자세히 설명해 주시겠습니까? 일반적으로 별도의 M-x ansi-term버퍼 에서 IPython을 시작한 다음 isend-mode 를 사용 하여 소스 버퍼를 IPython 버퍼에 바인딩하여 자동으로 %paste마술을 IPython 버퍼로 보내는 키보드 단축키로 코드를 IPython 인터프리터에 보낼 수 있습니다 . 이를 통해 IPython에서 지역을 빠르게 테스트 할 수 있습니다. 나는 항상이 IPython 쉘에서 내 프로그램을 실행 run하고 사용합니다.embed() 하고 중지 데 합니다.
Amelio Vazquez-Reina 2016 년

3
예를 들어 코드를 단계별로 실행하면 소스 코드가 다른 버퍼에서 현재 실행 지점을 가리키는 화살표와 함께 열립니다. isend-mode와 마찬가지로 send-region 명령도 있습니다.
tkf

감사합니다 @ tkf 해당 셸을 ipdb사용하여 디버깅 세션을 시작하고 python.el이와 같은 것을 어떻게 가질 수 send-region있습니까? 일반적으로 이에 대한 자세한 정보는 어디에서 찾을 수 있습니까?
Amelio Vazquez-Reina

내가 사용 %run또는 %debug. 나도 import ipdb; ipdb.set_trace()작동하는 것 같아요 . ipdb에 여러 줄을 보낼 수 있다고 생각하지 않습니다. 그것은 ipdb의 한계입니다. 그러나 아마도 %paste트릭이 작동합니다. IPython dev에 기능 요청을 보낼 수 있습니다.
tkf


6

"!"접두사 pdb에 입력 한 명령에 대한 기호는 IPython 쉘에서 작업을 수행하는 것과 동일한 효과를 갖는 것 같습니다. 특정 기능 또는 변수 이름에 대한 도움말에 액세스하는 데 사용됩니다. 어쩌면 이것이 어느 정도 도움이 될 것입니다. 예를 들어

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

그러나! help (numpy.transpose)는 numpy.transpose에 대한 도움말 페이지를 제공합니다. 변수 이름과 마찬가지로 변수 l이 있다고 가정하면 pdb에 "l"을 입력하면 코드가 나열되지만! l은 l의 값을 인쇄합니다.


2
이것은 불쾌한 pdb입니다. 알만한 가치가 있습니다.
Wilfred Hughes

4

이 팁 을 사용해 보셨습니까 ?

또는 더 나은 방법으로 ipython을 사용하고 다음을 호출하십시오.

from IPython.Debugger import Tracer; debug_here = Tracer()

그럼 당신은 사용할 수 있습니다

debug_here()

중단 점을 설정하려고 할 때마다


4

당신은 IPython 내에서 시작할 수 있습니다 ipdb!

ipdb디버거 1을 유도하십시오 .

import idpb; ipdb.set_trace()

콘솔 2 에서 IPython 입력하십시오 .ipdb>

from IPython import embed; embed()

다음에서 ipdb>콘솔로 돌아갑니다 IPython:

exit

Emacs를 사용하기에 운이 좋으면 상황을 더욱 편리하게 만들 수 있습니다!

을 사용해야합니다 M-x shell. 사용 yasnippetBM , 다음 코드를 정의합니다. ipdb편집기 의 텍스트 가 set-trace줄로 바뀝니다. 스 니펫을 삽입하면 쉽게 눈에 잘 띄고 탐색 할 수 있도록 선이 강조 표시됩니다. 를 사용하여 M-x bm-next이동합니다.

# -*- mode: snippet -*-
# name: ipdb
# key: ipdb
# expand-env: ((yas-after-exit-snippet-hook #'bm-toggle))
# --
import ipdb; ipdb.set_trace()

1 한 줄에 모두 쉽게 삭제할 수 있습니다. 이후 imports에만이 양식 보장하지만이 한 번 발생 ipdb하면 별도의 오버 헤드를 필요로 할 때 가져옵니다.

2 파일 IPython 내에서.pdbrc 가져 와서 입력 내용을 저장할 수 있습니다 .

try:
    from IPython import embed
except:
    pass

이를 통해 IPython이 설치되어있을 때만 전화 embed()를 걸 수 있습니다 ipdb.


3

한 가지 옵션은 Spyder 와 같은 IDE를 사용하여 디버깅하는 동안 실제로 IPython 콘솔을 사용하여 코드와 상호 작용할 수 있도록하는 것입니다. 사실, Spyder는 MATLAB과 매우 유사하여 의도적 인 것으로 추정됩니다. 여기에는 변수 관리자, 변수 편집, 문서에 대한 내장 액세스 등이 포함됩니다.


3

질문에 대한 정확하고 쉽고 멋지고 정확한 대답은 -d 플래그와 함께 % run 매크로를 사용하는 것입니다.

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

이것은 더 높아야합니다. 모듈 내에서 코드에 줄을 삽입 해야하는 경우 IPython을 다시 시작하여 모듈을 다시로드해야합니다. 이것으로, 나는 %save /tmp/foo.py x-y실행하고 디버그하고 싶은 코드를 원할 %run -d /tmp/foo.py때 중단 점을 설정할 수 있습니다. 좋은 답변입니다!
Romeo Valentin

2

embed () 콘솔에 exit ()를 입력하면 코드가 계속 진행되고 다음 embed () 행으로 이동합니다.


2

Pyzo IDE는 영업 이익 요구와 유사한 기능을 가지고있다. 디버그 모드에서 시작할 필요는 없습니다. MATLAB과 마찬가지로 명령이 셸에서 실행됩니다. 일부 소스 코드 줄에 중단 점을 설정하면 IDE에서 실행을 중지하고 일반 IPython 명령을 디버그하고 실행할 수 있습니다.

그러나 다른 중단 점을 설정하지 않으면 step-into가 (아직?) 제대로 작동하지 않는 것처럼 보입니다 (즉, 한 줄에서 멈추고 다른 기능으로 스테핑).

여전히 MATLAB에서 나왔지만 이것이 내가 찾은 최고의 솔루션 인 것 같습니다.


2

python 3.2부터는 interact전체 python / ipython 명령 공간에 액세스 할 수있는 명령이 있습니다.


1

Emacs의 IPython-shell 내부에서 실행하면 pdb.set_trace ()를 통해 설정된 중단 점이 작동합니다.

python-mode.el, Mx ipython RET 등으로 확인되었습니다.


1

새로운 코드 개발

IPython 내부 디버깅

  1. Jupyter / IPython 셀 실행을 사용하여 실험 반복 속도 향상
  2. 단계별로 %% debug 사용

세포 예 :

%%debug
...: for n in range(4):
...:    n>2

기존 코드 디버깅

디버깅 내부의 IPython

  1. 부서진 단위 테스트 디버깅 : pytest ... --pdbcls=IPython.terminal.debugger:TerminalPdb --pdb
  2. 테스트 케이스의 외부 디버깅 : breakpoint(), python -m ipdb, 등
  3. 디버거에서 필요한 전체 IPython 기능을위한 IPython.embed ()

파이썬에 대한 생각

MATLAB이 파이썬을 훌륭하게 수행하는 많은 것들이 여전히 가지고 있지 않으며 실제로 언어의 모든 것이 생산 속도보다 개발 속도를 선호하기 때문에 OP에 동의합니다. 어쩌면 나는 CPython에 사소한 버그 수정 이상을 제공 할 것입니다.

https://github.com/ipython/ipython/commit/f042f3fea7560afcb518a1940daa46a72fbcfa68

참조 는 디버깅 IPython의 명령을 실행할 수 있습니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.