Cách thực thi các câu lệnh nhiều dòng trong trình gỡ lỗi của chính Python (PDB)


157

Vì vậy, tôi đang chạy một kịch bản Python trong đó tôi đang gọi trình gỡ lỗi của Python, PDB bằng cách viết:

import ipdb; ipdb.set_trace()

(Phiên bản PDB của iPython, mặc dù đối với vấn đề tôi không nghĩ nó tạo ra sự khác biệt; tôi chỉ sử dụng nó cho đầu ra có màu).

Bây giờ, khi tôi đến trình gỡ lỗi, tôi muốn thực thi một câu lệnh nhiều dòng như mệnh đề if hoặc vòng lặp for nhưng ngay khi tôi gõ

if condition:

và nhấn phím quay lại, tôi nhận được thông báo lỗi *** SyntaxError: invalid syntax (<stdin>, line 1)

Làm thế nào một người có thể thực thi các câu lệnh nhiều dòng trong PDB? Nếu không thể, có cách nào để thực hiện mệnh đề if hoặc vòng lặp for không?

Câu trả lời:


265

Bạn có thể làm điều này trong khi ở pdb để khởi chạy phiên Python tương tác tạm thời với tất cả các biến cục bộ có sẵn:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Khi bạn hoàn tất, sử dụng Ctrl-D để trở về dấu nhắc pdb thông thường.

Chỉ cần không nhấn Ctrl-C, điều đó sẽ chấm dứt toàn bộ phiên pdb.


46
Có vẻ như điều tương tự có thể đạt được bằng cách sử dụng interactlệnh pdb ( như tôi đã học được từ thông báo theo dõi lỗi này ).
gerrit

3
Tại sao !cần thiết trong importtuyên bố?
Indradhanush Gupta

19
Có lẽ không cần thiết, nhưng tôi có thói quen tiền tố tất cả các câu lệnh Python trong pdb với !, để tránh tai nạn. Ví dụ, c = 42trong pdb sẽ tiếp tục thực hiện thay vì gán cho biến c.
Marius Gedminas

8
@MariusGedminas điều khó chịu nhất với PDB! Sẽ rất tuyệt nếu các lệnh của họ phải được thêm tiền tố ...
Ian Clark

Lưu ý: Ctrl-D dường như cũng là cách thoát đúng interact, nhưng nó không hoạt động tốt với Spyder đối với tôi.
Josiah Yoder

69

Trong python3 ipdb(và pdb) có một lệnh gọi là tương tác . Nó có thể được sử dụng để:

Bắt đầu một trình thông dịch tương tác (sử dụng mô-đun ) có không gian tên toàn cầu chứa tất cả các tên (toàn cầu và cục bộ) được tìm thấy trong phạm vi hiện tại.

Để sử dụng nó, chỉ cần nhập interacttại dấu nhắc pdb. Trong số những thứ khác, nó hữu ích cho việc áp dụng mã trải dài trên nhiều dòng và cũng để tránh việc vô tình kích hoạt các lệnh pdb khác.


2
Nó cho tôi "NameError: tên 'tương tác' không được xác định" khi làm điều đó.
Jason

1
@jason phiên bản 3.2 trở lên
vaer-k

2
Điều đó giải thích. Tôi đã ở trăn 2.7.
Jason

Cẩn thận điều này thực sự đã gây ra một lỗi mà tương tác có thể không được xác định và thoát khỏi quy trình
Camron_Godbout

1
Tôi nghĩ đề xuất để tránh interactlà một đề nghị quá mạnh mẽ. 90% đây là tất cả những gì tôi cần, và nó dễ dàng hơn rất nhiều so vớifrom IPython import embed; embed()
vaer-k

43

Đề nghị của tôi là sử dụng nhúng IPython.

ipdb> from IPython import embed; embed()

2
Nếu bạn có giá trị không được xác định lỗi trong việc hiểu danh sách, hãy thử sử dụng từ IPython import embed; embed(user_ns=locals()).
fx-kirin

1
điều này làm việc tốt hơn nhiều đối với tôi so với câu trả lời được chấp nhận. Ví dụ: nó cho phép chỉnh sửa đa dòng một cách thích hợp - như sao lưu một vài dòng và sửa một cái gì đó, vì vậy bạn không phải viết lại toàn bộ biểu thức đa dòng của mình một lần nữa ... Tôi sẽ chuyển địa phương thành @ fx-kirin đề nghị.
ZeDuS

33

Bên trong trình thông dịch hoặc trình gỡ lỗi Python (2.7.1), nhập pdb), bạn có thể thực thi một câu lệnh nhiều dòng với cú pháp sau.

for i in range(5): print("Hello"); print("World"); print(i)

Lưu ý: Khi tôi ở trong trình thông dịch, tôi phải nhấn return hai lần trước khi mã sẽ thực thi. Tuy nhiên, bên trong trình gỡ lỗi, tôi chỉ phải quay trở lại một lần.


5
Nó không cho phép chạy bất cứ thứ gì sâu hơn một cấp.
Antony Hatchkins

7

Có trường hợp đặc biệt nếu bạn muốn một vài lệnh được thực thi khi nhấn điểm dừng. Sau đó là lệnh gỡ lỗi commands. Nó cho phép bạn nhập nhiều dòng lệnh và sau đó kết thúc toàn bộ chuỗi bằng endtừ khóa. Thêm với (pdb) help commands.


2

Tôi không biết nếu bạn có thể làm điều này, đó sẽ là một tính năng tuyệt vời cho ipdb. Tất nhiên, bạn có thể sử dụng danh sách hiểu và thực hiện các biểu thức đa dòng đơn giản như:

if y == 3: print y; print y; print y;

Bạn cũng có thể viết một số chức năng trước để làm bất cứ điều gì bạn cần làm mà thường sẽ mất nhiều dòng.


-6

Viết mã của bạn trong trình soạn thảo văn bản, sau đó dán mã vào trình gỡ lỗi:

if True:
    print('a')

Đó là một giải pháp ngớ ngẩn, nhưng cũng bẩn nhanh chóng và làm việc. Nó hoạt động trên thiết bị đầu cuối Linux, nhưng tôi không chắc liệu nó có hoạt động trên bảng điều khiển Windows hay không.


3
Thành thật mà nói, tôi sẽ không nói rằng việc gọi một chương trình bên ngoài, viết, sao chép và dán là nhanh chóng , chỉ là bẩn thỉu: P
Nhà khoa học dữ liệu

4
Điều này, không làm việc cho tôi và thew*** SyntaxError: unexpected EOF while parsing
Yash Kant
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.