ত্রুটিতে স্বয়ংক্রিয়ভাবে পাইথন ডিবাগার শুরু করা


216

এটি এমন একটি প্রশ্ন যা আমি বেশ কিছুদিন ধরেই ভাবছিলাম, তবুও আমি কখনই উপযুক্ত সমাধান পাইনি। যদি আমি কোনও স্ক্রিপ্ট রান করি এবং আমি এটি দেখতে পাই তবে একটি সূচিপত্র বলি, পাইথন ত্রুটির লাইন, অবস্থান এবং দ্রুত বর্ণনা প্রিন্ট করে। কোনও ত্রুটি দেখা দিলে স্বয়ংক্রিয়ভাবে পিডিবি শুরু করা সম্ভব? আমি ফাইলের শীর্ষে কোনও অতিরিক্ত আমদানি বিবৃতি, বা কোডের কয়েকটি অতিরিক্ত লাইন থাকার বিরুদ্ধে নই।


12
আপনি কি উত্তরটি গ্রহণযোগ্য তা পরিবর্তন করার বিষয়টি বিবেচনা করেছেন?
জুস্ট

উত্তর:


127

আপনি ব্যতিক্রম ট্রেসব্যাক মুদ্রণ করতে traceback.print_exc ব্যবহার করতে পারেন । তারপর ব্যবহার sys.exc_info ট্রেসব্যাক এবং পরিশেষে কল বের করে আনতে pdb.post_mortem যে ট্রেসব্যাক সঙ্গে

import pdb, traceback, sys

def bombs():
    a = []
    print a[0]

if __name__ == '__main__':
    try:
        bombs()
    except:
        extype, value, tb = sys.exc_info()
        traceback.print_exc()
        pdb.post_mortem(tb)

আপনি যদি ফ্রেডের লোকাল যেখানে ব্যতিক্রমটি উদ্ভূত হয়েছে আপনি সেখানে ব্যবহার করে কোড. interact সহ একটি ইন্টারেক্টিভ কমান্ড লাইন শুরু করতে চান

import traceback, sys, code

def bombs():
    a = []
    print a[0]

if __name__ == '__main__':
    try:
        bombs()
    except:
        type, value, tb = sys.exc_info()
        traceback.print_exc()
        last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb
        frame = last_frame().tb_frame
        ns = dict(frame.f_globals)
        ns.update(frame.f_locals)
        code.interact(local=ns)

প্রথম সমাধানটি অজগর রান্নার
দিরকজট

3
যেহেতু দ্বিতীয়টি প্রাক্তনটির উপর প্রসারিত বলে মনে হয় কেন কেউ codeতার চেয়ে বেশি পছন্দ করবে pdb?
কে 3 --- আরএনসি

আমার কি একই প্রশ্ন আছে? আপনি কেন পছন্দ করবেন code?
এআরএইচ

2
তারপরে sys.exc_infoট্রেসব্যাকটি বের করতে এবং অবশেষে pdb.post_mortemসেই ট্রেসব্যাকের সাথে কল করতে ব্যবহার করুন । আপনার ট্রেসব্যাক অবজেক্টটি পাস করার দরকার নেই pdb.post_mortemদস্তাবেজগুলি থেকে : যদি কোনও ট্রেসব্যাক না দেওয়া হয়, তবে এটি বর্তমানে ব্যবহৃত ব্যতিক্রমগুলির একটির ব্যবহার করে (ডিফল্টটি ব্যবহার করতে হলে অবশ্যই একটি ব্যতিক্রম হ্যান্ডেল করা উচিত)।
পাইওটর ডব্রোগস্ট

2
@ পাইওটারডব্রোগস্ট ভাল পয়েন্ট আমি মনে করি এটি আরও বেশি সহায়ক যে আপনি কোনও টিবি অবজেক্টকে পাস করতে পারবেন, যদিও এটি এপিআইকে আরও ভাল করে দেখায়। উভয় বিকল্প বিদ্যমান তা জেনে রাখা ভাল।
ডেভিডা

453
python -m pdb -c continue myscript.py

আপনি যদি -c continueপতাকাটি সরবরাহ না করেন তবে কার্যকর করা শুরু হলে আপনাকে 'সি' (চালিয়ে যাওয়ার জন্য) প্রবেশ করতে হবে enter তারপরে এটি ত্রুটি বিন্দুতে চলে যাবে এবং আপনাকে সেখানে নিয়ন্ত্রণ দেবে। ইকজএক্স দ্বারা উল্লিখিত হিসাবে , এই পতাকাটি পাইথন ৩.২ এ একটি নতুন সংযোজন, সুতরাং পূর্ববর্তী পাইথন সংস্করণগুলির জন্য 'সি' প্রবেশ করা প্রয়োজন ( https://docs.python.org/3/library/pdb.html দেখুন )।


5
" এন্টার 'সি' ' উল্লেখ করার জন্য ধন্যবাদ - আমি সাধারণত' আর 'প্রবেশ করতাম (" রান "এর জন্য), এর অভ্যন্তরে ব্যবহৃত হত gdb; এবং আপনি যখন 'আর' প্রবেশ করান pdb, প্রোগ্রামটি সত্যই সঞ্চালিত হয়, তবে ত্রুটি হয়ে থামবে না (ব্যাকট্র্যাস উত্পন্ন করবে না); আমি এটি পড়া না হওয়া পর্যন্ত আমাকে হতবাক করে দিয়েছিল। চিয়ার্স!
sdaau

3
ভিনিট, এটি আপনাকে ডিবাগার দিয়ে চালু করবে, সুতরাং "বিস্মরণ" লিখুন এবং ত্রুটি দেখা না দেওয়া পর্যন্ত এটি চলবে। সেখান থেকে আপনি অন্যান্য পিডিবি সেশনের মতো চলক ইত্যাদি পরিদর্শন করতে পারেন।
ক্যাথরিন ডেভলিন

40
দয়া করে ওপি, এটি একটি উত্তর হিসাবে গ্রহণ করুন। এটি সবচেয়ে দরকারী এবং আমি এটি পড়ার আগ পর্যন্ত আমি অন্যগুলি পড়তে 5 মিনিট নষ্ট করেছি ... এটি প্রথম হওয়া উচিত!
heেগেগাস

4
এটি একই সাথে কাজ করে ipdb; এবং অবশ্যই স্ক্রিপ্ট পরে যুক্তি যুক্ত করা যেতে পারে!
tutuDajuju

20
এটি পাইথন ২.7 নিয়ে কাজ করে না। docs.python.org/3/library/pdb.html : "সংস্করণে নতুন 3.2: pdb.py এখন একটি -c বিকল্প গ্রহণ করে যা আদেশগুলি কার্যকর করে"
eqzx

68

নিম্নলিখিত মডিউলটি ব্যবহার করুন:

import sys

def info(type, value, tb):
    if hasattr(sys, 'ps1') or not sys.stderr.isatty():
    # we are in interactive mode or we don't have a tty-like
    # device, so we call the default hook
        sys.__excepthook__(type, value, tb)
    else:
        import traceback, pdb
        # we are NOT in interactive mode, print the exception...
        traceback.print_exception(type, value, tb)
        print
        # ...then start the debugger in post-mortem mode.
        # pdb.pm() # deprecated
        pdb.post_mortem(tb) # more "modern"

sys.excepthook = info

এটির নাম দিন debug(বা যা আপনার পছন্দ হয়) এবং এটি আপনার অজগর পথে কোথাও রেখে দিন।

এখন, আপনার স্ক্রিপ্টের শুরুতে, কেবল একটি যুক্ত করুন import debug


2
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত - এটির জন্য বিদ্যমান কোডের কোনও সংশোধন বা try-catchযা কেবল কুৎসিত আইএমও তে সমস্ত মোড়ানো দরকার হয় না ।
সাইফার

আমি এই উত্তরটি বরং ঘন ঘন পছন্দ করি তবে pudbতার চেয়ে বেশি পছন্দ করি pdb। অনুলিপি-অনুলিপি করতে ফিরে যান, যা অবশ্যই আমার জীবনে আদেশের অভাব সম্পর্কে কিছু বলে।
স্টেলেডোগ

47

আইপিথনের এই আচরণটি টগল করার জন্য একটি আদেশ রয়েছে: % পিডিবি । এটি আপনি বর্ণিত ঠিক তেমনটি করে, সম্ভবত আরও কিছুটা বেশি (সিনট্যাক্স হাইলাইটিং এবং কোড সমাপ্তির সাথে আপনাকে আরও তথ্যমূলক ব্যাকট্রেস দেয়)। এটি অবশ্যই চেষ্টা করার মতো!


3
এবং এটি এর একমাত্র যুক্তিসঙ্গত উত্তর।
মাইকেল


4
নোট করুন - @ মথিথ্যাশ লিঙ্কযুক্ত ডক্সে যেমন উল্লেখ করা হয়েছে - ত্রুটি দেখা দেওয়ার পরে%debug একজনকে ডিবাগারটি খোলার অনুমতি দেয় । আমি প্রায়শই এটিকে পছন্দ করি । (ট্রেড-অফ কেবলমাত্র টাইপ করছে যখন আপনি কোনও ত্রুটি ডিবাগ করতে চান না বনাম প্রতিবার টাইপ করে কোনও ত্রুটি ডিবাগ করতে চান।)%pdbq%debug
ব্রাহাম স্নাইডার

1
এটিও নোট করুন যে প্রতিটি সেশনের জন্য c.InteractiveShell.pdb = Trueকারও ipython_config.pyকারনে সেটিংস %pdbস্বয়ংক্রিয়ভাবে চালু হয় ।
ব্রাহাম স্নাইডার

33

এটি ডিবাগার নয়, তবে সম্ভবত এটি কার্যকর (?)

আমি জানি আমি গুডো কোথাও একটি বক্তৃতায় এটি উল্লেখ করতে শুনেছি।

আমি কেবল অজগর - ?, পরীক্ষা করেছি এবং যদি আপনি -i কমান্ড ব্যবহার করেন তবে আপনার স্ক্রিপ্টটি যেখানে থামেছে সেখানে আপনি ইন্টারেক্ট করতে পারবেন।

সুতরাং এই স্ক্রিপ্ট দেওয়া:

testlist = [1,2,3,4,5, 0]

prev_i = None
for i in testlist:
    if not prev_i:
        prev_i = i
    else:
        result = prev_i/i

আপনি এই আউটপুট পেতে পারেন!

PS D:\> python -i debugtest.py
Traceback (most recent call last):
  File "debugtest.py", line 10, in <module>
    result = prev_i/i
ZeroDivisionError: integer division or modulo by zero
>>>
>>>
>>> prev_i
1
>>> i
0
>>>

সত্যি কথা বলতে, আমি এটি ব্যবহার করি নি, তবে আমার হওয়া উচিত, খুব দরকারী বলে মনে হচ্ছে।


লাইটওয়েট, তবে প্রায়শই কেবল যা প্রয়োজন
কেসব্যাশ

8
প্রায় হিসাবে দরকারী হিসাবে না, গ্লোবাল স্কোপ মধ্যে আরম্ভ। যে ক্রিয়াকলাপটি ক্র্যাশ হয়েছিল তা ঘুরে দাঁড়াতে পারে না।
পিক্সেলপ্যাক্স

21

আইপিথন কমান্ড লাইনে এটিকে সহজ করে তোলে:

python myscript.py arg1 arg2

আবার লেখা যেতে পারে

ipython --pdb myscript.py -- arg1 arg2

অথবা, একইভাবে, যদি মডিউলটি কল করে:

python -m mymodule arg1 arg2

আবার লেখা যেতে পারে

ipython --pdb -m mymodule -- arg1 arg2

--আইপিথনটিকে স্ক্রিপ্টের যুক্তিগুলি তার নিজের হিসাবে পড়া থেকে বিরত রাখতে নোট করুন ।

এতে পিডিবির পরিবর্তে বর্ধিত আইপিথন ডিবাগার (আইপিডিবি) শুরু করার সুবিধা রয়েছে।


9

আপনি যদি ব্যবহার করছেন ipython, প্রবর্তন টাইপ পরে%pdb

In [1]: %pdb
Automatic pdb calling has been turned ON

উদাহরণস্বরূপ
জুপিটার

6

আপনি যদি আইপথন পরিবেশ ব্যবহার করছেন, আপনি কেবল% ডিবাগ ব্যবহার করতে পারেন এবং শেল আপনাকে আইপিডিবি পরিবেশের সাথে পরিদর্শন করার জন্য আপত্তিকর লাইনে ফিরিয়ে নিয়ে যেতে পারে pointed একই.


মনে রাখবেন যে কোনও মডিউল ফাংশনে ত্রুটিটি ঘটলে আপনি ত্রুটিটি উত্পন্ন করে আপনার কোডের লাইনে ফিরে যাওয়ার জন্য ফ্রেম upএবং downকমান্ডের সাহায্যে নেভিগেট করতে পারেন ।
জিন পল

4

আপনি এই কোডটি আপনার কোডটিতে রাখতে পারেন:

import pdb ; pdb.set_trace()

আরও তথ্য: যে কোনও লাইনে পাইথন ডিবাগারটি শুরু করুন


8
এটি কোডটি থামায় এবং আপনি যে কমান্ডটি এই আদেশটি দিয়েছিলেন সেই লাইনে একটি ডিবাগার শুরু করে, যেখানে কোনও ব্যতিক্রম ঘটেছিল সেই লাইনে নয়
ব্লুফাস্ট

3

শুরুতে সি টাইপ না করে এটি চালানোর জন্য:

python -m pdb -c c <script name>

পিডিবির নিজস্ব কমান্ড লাইন আর্গুমেন্ট রয়েছে: -সিসি এক্সিকিউশন শুরুর সময় c (ontinue) কমান্ড কার্যকর করবে এবং ত্রুটি হওয়া পর্যন্ত প্রোগ্রামটি নিরবচ্ছিন্নভাবে চলবে run


3

পাইথন-এম পিডিবি স্ক্রিপ্ট.পিতে পাইথন ২..7 টি টিপতে শুরু করুন এবং এটি ত্রুটির দিকে চলে যাবে এবং ডিবাগের জন্য সেখানে ভেঙে যাবে।


1

আপনি যদি একটি মডিউল চালাচ্ছেন:

python -m mymodule

এবং এখন আপনি প্রবেশ করতে চান pdbযখন কোনও ব্যতিক্রম ঘটে তখন এটি করুন:

PYTHONPATH="." python -m pdb -c c mymodule/__main__.py

(বা আপনার প্রসারিতPYTHONPATH )। PYTHONPATHযাতে মডিউল পথ পাওয়া যায় প্রয়োজন, যেহেতু আপনি দৌড়াচ্ছে pdbএখন মডিউল।


0

অনুক্রমের শীর্ষস্থানীয় ব্যতিক্রম শ্রেণীর কনস্ট্রাক্টরের ভিতরে একটি ব্রেকপয়েন্ট রাখুন এবং বেশিরভাগ সময় আপনি দেখতে পাবেন যেখানে ত্রুটিটি উত্থাপিত হয়েছিল।

ব্রেকপয়েন্ট স্থাপন করা মানে যা বোঝাতে চাইছেন: আপনি একটি আইডিই, বা pdb.set_trace, বা যা কিছু ব্যবহার করতে পারেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.