ویدیو آموزش ماژول pdb در پایتون

August 2021

در توسعه نرم افزار ، دیباگینگ یا اشکال زدایی فرایند جستجو و سپس حل مشکلاتی است که مانع از اجرای صحیح نرم افزار می شود. Python debugger محیط اشکال زدایی را برای برنامه های پایتون فراهم می کند. این برنامه از تنظیم نقاط شکست شرطی، گذر از طریق کد منبع به صورت خطی ، بازرسی پشته و موارد دیگر پشتیبانی می کند.

 

اشکال زدایی یکی از فعالیتهای نامطلوب در توسعه نرم افزار است و در عین حال ، یکی از مهمترین وظایف در چرخه عمر توسعه نرم افزار است. در برخی مراحل ، هر برنامه نویس باید کد خود را اشکال زدایی کند ، مگر اینکه یک برنامه نرم افزاری بسیار اساسی را توسعه دهد.

 

ماژول pdb یک اشکال زدایی کد منبع تعاملی را برای برنامه های پایتون تعریف می کند. این برنامه از تنظیم نقاط شکست (مشروط) و یک مرحله ای در سطح خط منبع ، بازرسی فریم های پشته ، فهرست کد منبع و ارزیابی کد پایتون دلخواه در زمینه هر چارچوب پشته پشتیبانی می کند.

 

این ویدیو مناسب افرادیست که پایتون را به خوبی بلد هستند، اگر تا به حال با پایتون کار نکرده‌اید میتوانید دوره آموزش پایتون  را ببینید.

 


 

کار با دیباگر پایتون به صورت تعاملی

دیباگر پایتون به عنوان بخشی از کتابخانه استاندارد پایتون به عنوان ماژولی به نام pdb ارائه می شود. دیباگر نیز قابل توسعه است و به عنوان کلاس Pdb تعریف شده است. برای کسب اطلاعات بیشتر می توانید اسناد رسمی pdb را مطالعه کنید.

 

ما ابتدا با یک برنامه کوتاه که دارای دو متغیر سراسری است ، کار می کنیم ، یک تابع که یک حلقه تو در تو ایجاد می کند ، و  if __name__ == '__main__': ساختاری است که تابع () nested_loop را فراخوانی می کند.

 

num_list = [500, 600, 700]
alpha_list = ['x', 'y', 'z']


def nested_loop():
    for number in num_list:
        print(number)
        for letter in alpha_list:
            print(letter)

if __name__ == '__main__':
    nested_loop()

 

اکنون می توانیم این برنامه را از طریق اشکال زدایی پایتون با استفاده از دستور زیر اجرا کنیم:

python -m pdb looping.py

 

پرچم خط فرمان -m هر ماژول پایتون را برای شما وارد کرده و به صورت اسکریپت اجرا می کند. در این مورد ما در حال وارد کردن و اجرای ماژول pdb هستیم ، که همانطور که در بالا نشان داده شده است به خط فرمان منتقل می کنیم.

 

پس از اجرای این دستور ، خروجی زیر را دریافت خواهید کرد:

> /Users/sammy/looping.py(1)<module>()
-> num_list = [500, 600, 700]
(Pdb) 

 

در خروجی، خط اول شامل نام ماژول فعلی (همانطور که با <module> نشان داده شده است) با یک مسیر دایرکتوری ، و شماره خط چاپی که در زیر آمده است (در این مورد 1 است ، اما در صورت وجود کامنت یا سایر موارد غیر قابل اجرا) خط می تواند یک عدد بالاتر باشد). خط دوم خط فعلی کد منبع را نشان می دهد که در اینجا اجرا شده است، زیرا pdb یک کنسول تعاملی برای اشکال زدایی ارائه می دهد. می توانید از دستور help برای یادگیری دستورات آن و از دستور help برای کسب اطلاعات بیشتر در مورد یک دستور خاص استفاده کنید. توجه داشته باشید که کنسول pdb با پوسته تعاملی پایتون متفاوت است.

 

هنگامی که به پایان برنامه شما رسید ، دیباگر پایتون به طور خودکار شروع به کار می کند. هر زمان که می خواهید کنسول pdb را ترک کنید ، دستور quit یا exit را تایپ کنید. اگر می خواهید برنامه ای را به صراحت در هر مکانی از برنامه راه اندازی مجدد کنید ، می توانید این کار را با اجرای دستور run انجام دهید.

 


 

استفاده از Debugger برای حرکت در یک برنامه

هنگام کار با برنامه ها در اشکال زدایی پایتون ، احتمالاً از دستورات list ، next و step برای حرکت در کد خود استفاده می کنید. در این قسمت به بررسی این دستورات می پردازیم.

 

در پوسته ، می توان لیست فرمان را تایپ کرد تا زمینه را در اطراف خط فعلی بدست آورد. از خط اول برنامه looping.py که در بالا نمایش دادیم - num_list = [500 ، 600 ، 700] - که شبیه شکل زیر است:

(Pdb) list
  1  -> num_list = [500, 600, 700]
  2     alpha_list = ['x', 'y', 'z']
  3     
  4     
  5     def nested_loop():
  6         for number in num_list:
  7             print(number)
  8             for letter in alpha_list:
  9                 print(letter)
 10     
 11     if __name__ == '__main__':
(Pdb) 

 

خط فعلی با نویسه -> نشان داده می شود که در مورد ما اولین خط فایل برنامه است.

 

از آنجا که این یک برنامه نسبتاً کوتاه است ، تقریباً همه برنامه را با دستور list دریافت می کنیم. بدون ارائه آرگومان ، دستور list 11 خط در اطراف خط فعلی ارائه می دهد ، اما همچنین می توانید مشخص کنید که کدام خطوط شامل موارد زیر باشد:

(Pdb) list 3, 7
  3     
  4     
  5     def nested_loop():
  6         for number in num_list:
  7             print(number)
(Pdb) 

 

در اینجا ، ما درخواست کردیم که خطوط 3-7 با استفاده از فرمان 3 ، 7 نمایش داده شوند.

 

برای حرکت خط به خط در برنامه ، می توانیم از step یا next استفاده کنیم:

(Pdb) step
> /Users/sammy/looping.py(2)<module>()
-> alpha_list = ['x', 'y', 'z']
(Pdb) 

 

(Pdb) next
> /Users/sammy/looping.py(2)<module>()
-> alpha_list = ['x', 'y', 'z']
(Pdb) 

 

تفاوت بین step و next این است که step در یک تابع فراخوانی شده متوقف می شود ، در حالی که next عملکردهای بعدی را اجرا می کند تا فقط در خط بعدی تابع فعلی متوقف شود. وقتی با تابع کار می کنیم می توانیم این تفاوت را مشاهده کنیم.

 

دستور step بعد از شروع به کار در حلقه ها تکرار می شود و دقیقاً نشان می دهد که حلقه در حال انجام چه کاری است ، زیرا ابتدا یک عدد را با چاپ (شماره) چاپ می کند و سپس برای چاپ حروف با چاپ (حرف) ، بازگشت به شماره و غیره:

(Pdb) step
> /Users/sammy/looping.py(5)<module>()
-> def nested_loop():
(Pdb) step
> /Users/sammy/looping.py(11)<module>()
-> if __name__ == '__main__':
(Pdb) step
> /Users/sammy/looping.py(12)<module>()
-> nested_loop()
(Pdb) step
--Call--
> /Users/sammy/looping.py(5)nested_loop()
-> def nested_loop():
(Pdb) step
> /Users/sammy/looping.py(6)nested_loop()
-> for number in num_list:
(Pdb) step
> /Users/sammy/looping.py(7)nested_loop()
-> print(number)
(Pdb) step
500
> /Users/sammy/looping.py(8)nested_loop()
-> for letter in alpha_list:
(Pdb) step
> /Users/sammy/looping.py(9)nested_loop()
-> print(letter)
(Pdb) step
x
> /Users/sammy/looping.py(8)nested_loop()
-> for letter in alpha_list:
(Pdb) step
> /Users/sammy/looping.py(9)nested_loop()
-> print(letter)
(Pdb) step
y
> /Users/sammy/looping.py(8)nested_loop()
-> for letter in alpha_list:
(Pdb)

 

در عوض ، دستور next کل عملکرد را بدون نمایش مرحله به مرحله اجرا می کند. بیایید با دستور exit جلسه جاری را ترک کنیم و سپس دوباره اشکال زدایی را شروع کنیم:

python -m pdb looping.py

 

اکنون می توانیم با دستور next کار کنیم:

(Pdb) next
> /Users/sammy/looping.py(5)<module>()
-> def nested_loop():
(Pdb) next
> /Users/sammy/looping.py(11)<module>()
-> if __name__ == '__main__':
(Pdb) next
> /Users/sammy/looping.py(12)<module>()
-> nested_loop()
(Pdb) next
500
x
y
z
600
x
y
z
700
x
y
z
--Return--
> /Users/sammy/looping.py(12)<module>()->None
-> nested_loop()
(Pdb)  

 

هنگام مرور کد خود ، ممکن است بخواهید مقدار ارسال شده به یک متغیر را بررسی کنید ، که می توانید با دستور pp انجام دهید ، که مقدار عبارت را با استفاده از ماژول pprint بسیار چاپ می کند:

(Pdb) pp num_list
[500, 600, 700]
(Pdb) 

اکثر دستورات در pdb دارای نام مستعار کوتاه تر هستند. برای step آن فرم کوتاه s است ، و برای next آن n است. دستور Help نام مستعار موجود را لیست می کند. همچنین می توانید با فشردن کلید ENTER در اعلان، آخرین فرمانی را که فراخوانده اید فراخوانی کنید.

 


 

Breakpoints

شما معمولاً با برنامه های بزرگتری نسبت به مثال بالا کار خواهید کرد ، بنابراین احتمالاً به جای گذراندن یک برنامه کامل، به دنبال توابع یا خطوط خاصی هستید. با استفاده از دستور break برای تنظیم نقاط شکست ، برنامه را تا نقطه وقفه مشخص اجرا می کنید.

 

وقتی نقطه شکست را وارد می کنید ، اشکال زدایی یک شماره به آن اختصاص می دهد. اعداد اختصاص داده شده به نقاط شکست ، اعداد صحیح متوالی هستند که با عدد 1 شروع می شوند ، که هنگام کار با نقاط شکست می توانید به آنها مراجعه کنید.

 

نقاط زیر را می توان با رعایت نحو <program_file>:<line_number> در خطوط خاصی قرار داد:

(Pdb) break looping.py:5
Breakpoint 1 at /Users/sammy/looping.py:5
(Pdb)

 

Clear و سپس y را برای حذف همه نقاط شکست فعلی تایپ کنید. سپس می توانید یک نقطه شکست در جایی که یک تابع تعریف شده است قرار دهید:

(Pdb) break looping.nested_loop
Breakpoint 1 at /Users/sammy/looping.py:5
(Pdb) 

 

برای حذف نقاط شکست فعلی ، clear و سپس y را تایپ کنید. همچنین می توانید یک شرط تنظیم کنید:

(Pdb) break looping.py:7, number > 500
Breakpoint 1 at /Users/sammy/looping.py:7
(Pdb)     

 

حال ، اگر دستور continue را اجرا کنیم ، برنامه زمانی که عدد x بیشتر از 500 ارزیابی شود (یعنی وقتی در تکرار دوم حلقه خارجی برابر با 600 تنظیم شود) ، برنامه break می شود:

(Pdb) continue
500
x
y
z
> /Users/sammy/looping.py(7)nested_loop()
-> print(number)
(Pdb) 

 

برای مشاهده لیستی از نقاط شکست که در حال حاضر برای اجرا تنظیم شده اند، از فرمان break بدون هیچ گونه استدلال استفاده کنید. اطلاعاتی در مورد ویژگی های نقطه شکست (های) تعیین شده دریافت خواهید کرد:

(Pdb) break
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at /Users/sammy/looping.py:7
    stop only if number > 500
    breakpoint already hit 2 times
(Pdb) 

 

همچنین می توانیم با دستور disable و عدد نقطه شکست یک نقطه شکست را غیرفعال کنیم. در این جلسه ، یک نقطه شکست دیگر اضافه می کنیم و سپس اولین مورد را غیرفعال می کنیم:

(Pdb) break looping.py:11
Breakpoint 2 at /Users/sammy/looping.py:11
(Pdb) disable 1
Disabled breakpoint 1 at /Users/sammy/looping.py:7
(Pdb) break
Num Type         Disp Enb   Where
1   breakpoint   keep no    at /Users/sammy/looping.py:7
    stop only if number > 500
    breakpoint already hit 2 times
2   breakpoint   keep yes   at /Users/sammy/looping.py:11
(Pdb) 

 

برای فعال کردن نقطه شکست ، از فرمان enable و برای حذف کامل نقطه شکست ، از دستور clear استفاده کنید:

(Pdb) enable 1
Enabled breakpoint 1 at /Users/sammy/looping.py:7
(Pdb) clear 2
Deleted breakpoint 2 at /Users/sammy/looping.py:11
(Pdb) 

 

نقاط شکست در pdb کنترل زیادی را در اختیار شما قرار می دهد. برخی از ویژگیهای اضافی عبارتند از نادیده گرفتن نقاط شکست در طول تکرار فعلی برنامه با دستور ignore (مانند نادیده گرفتن 1) ، ایجاد اقدامات در نقطه شکست با فرمان commands (مانند دستور 1) و ایجاد نقاط وقفه موقت که به طور خودکار پاک می شوند اولین بار که برنامه اجرا می شود با دستور tbreak (برای وقفه موقت در خط 3 ، برای مثال ، می توانید tbreak 3 را تایپ کنید).

 


 

ادغام pdb در برنامه ها

با وارد کردن ماژول pdb و اضافه کردن تابع pdb pdb.set_trace () در بالای خطی که می خواهید break شروع شود ، می توانید جلسه اشکال زدایی را آغاز کنید.

 

در برنامه نمونه بالا ، ما عبارت import و عملکردی را که می خواهیم وارد اشکال زدایی کنیم اضافه می کنیم. برای مثال ما ، اجازه دهید آن را قبل از حلقه تو در تو اضافه کنیم.

# Import pdb module
import pdb

num_list = [500, 600, 700]
alpha_list = ['x', 'y', 'z']


def nested_loop():
    for number in num_list:
        print(number)

        # Trigger debugger at this line
        pdb.set_trace()
        for letter in alpha_list:
            print(letter)

if __name__ == '__main__':
    nested_loop()

 

با افزودن اشکال زدایی به کد خود نیازی نیست برنامه خود را به روش خاصی راه اندازی کنید یا به یاد داشته باشید که نقاط شکست را تنظیم کنید.

 

وارد کردن ماژول pdb و اجرای تابع pdb.set_trace () به شما امکان می دهد برنامه خود را طبق معمول شروع کرده و اشکال زدایی را از طریق اجرای آن اجرا کنید.

 

ارسال نظر

تلاش میکنم سوالات شما را در کمتر از یک روز پاسخ بدم