0
user Programlama Akademi
28-01-2025 5:17 PM
Python

Python Hata Ayıklayıcıyı Kullanma

Giriş

Yazılım geliştirme sürecinde hata ayıklama, yazılımın doğru çalışmasını engelleyen sorunları bulma ve çözme işlemidir.

Python hata ayıklayıcısı, Python programları için bir hata ayıklama ortamı sağlar. Şartlı durma noktaları belirlemeyi, kaynak kodu birer satır olarak takip etmeyi, yığın incelemeyi ve daha fazlasını destekler.

Python Hata Ayıklayıcı ile Etkileşimli Çalışma

Python hata ayıklayıcı, pdb adlı bir modül olarak standart Python dağıtımının bir parçası olarak gelir. Hata ayıklayıcı ayrıca genişletilebilir ve Pdb sınıfı olarak tanımlanmıştır.

Bilgi: Bu eğitici yazıdaki örnek kodları takip etmek için, yerel sisteminizde bir Python etkileşimli kabuğu açmak amacıyla python3 komutunu çalıştırın. Daha sonra, >>> isteminden sonra örnekleri kopyalayabilir, yapıştırabilir veya düzenleyebilirsiniz.

Kısa bir programla başlayacağız. Bu programda iki genel değişken, iç içe bir döngü oluşturan bir fonksiyon ve if __name__ == '__main__': yapısı kullanılarak nested_loop() fonksiyonu çağrılacaktır.

looping.py

sayi_listesi = [500, 600, 700]
harf_listesi = ['x', 'y', 'z']

def ic_ice_dongu():
    for sayi in sayi_listesi:
        print(sayi)
        for harf in harf_listesi:
            print(harf)

if __name__ == '__main__':
    ic_ice_dongu()

Bu programı Python hata ayıklayıcı ile aşağıdaki komut kullanılarak çalıştırabiliriz:

$ python -m pdb looping.py

-m komut satırı bayrağı, herhangi bir Python modülünü sizin için içe aktarır ve bir betik olarak çalıştırır. Bu durumda, yukarıda gösterildiği gibi komuta geçirdiğimiz pdb modülünü içe aktarıyor ve çalıştırıyoruz. Bu komutu çalıştırdığınızda aşağıdaki çıktıyı alırsınız: Çıktı:

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

Çıktıda, ilk satır mevcut modül adını (<module> ile belirtilmiş) bir dizin yolu ile birlikte içerir ve ardından gelen yazdırılmış satır numarasını gösterir (bu durumda 1, ancak bir yorum satırı veya başka çalıştırılabilir olmayan bir satır varsa daha yüksek bir numara olabilir). İkinci satır, burada yürütülen kaynak kodun mevcut satırını gösterir ve pdb, hata ayıklama için etkileşimli bir konsol sağlar. Komutlarını öğrenmek için help komutunu, belirli bir komut hakkında daha fazla bilgi almak için help komut_adı komutunu kullanabilirsiniz. pdb konsolunun, Python etkileşimli kabuğundan farklı olduğunu unutmayın. Python hata ayıklayıcısı, programınızın sonuna ulaştığında otomatik olarak yeniden başlar. pdb konsolundan çıkmak istediğinizde, quit veya exit komutunu yazabilirsiniz. Programın herhangi bir yerinde açıkça yeniden başlatmak isterseniz, bunu run komutuyla yapabilirsiniz.

Bir Programda İlerlemek için Hata Ayıklayıcı Kullanma

Python hata ayıklayıcı ile program üzerinde çalışırken list, step ve next komutlarını kodunuzda ilerlemek için muhtemelen kullanacaksınız. Bu bölümde bu komutları ele alacağız. Kabuk içinde, mevcut satırın etrafındaki bağlamı almak için list komutunu yazabiliriz. Yukarıda gösterilen programın ilk satırındaki (sayi_listesi = [500, 600, 700]) durumu şu şekilde görünür:

(Pdb) list
  1  ->    sayi_listesi = [500, 600, 700]
  2      harf_listesi = ['x', 'y', 'z']
  3      
  4      
  5      def ic_ice_dongu():
  6          for sayi in sayi_listesi:
  7              print(sayi)
  8              for harf in harf_listesi:
  9                  print(harf)
 10      
 11      if __name__ == '__main__':
(Pdb)

Mevcut satır -> karakterleri ile belirtilmiştir, ki bu durumda program dosyasının ilk satırıdır. Bu nispeten kısa bir program olduğu için, list komutuyla neredeyse tüm programı geri alıyoruz. Argüman sağlamadan kullanıldığında, list komutu mevcut satırın etrafındaki 11 satırı döndürür, ancak hangi satırların dahil edileceğini de belirtebilirsiniz:

(Pdb) list 3, 7
  3      
  4      
  5      def ic_ice_dongu():
  6          for sayi in sayi_listesi:
  7              print(sayi)
(Pdb)

Burada list 3, 7 komutunu kullanarak 3-7 satırların görüntülenmesini istedik. Programda satır satır ilerlemek için step veya next komutlarını kullanabiliriz:

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

step ve next arasındaki fark, step bir çağrılan fonksiyonun içine dururken, next çağrılan fonksiyonları çalıştırır ve yalnızca mevcut fonksiyonun bir sonraki satırında durur. Bu farkı, fonksiyonlarla çalışırken daha net görebiliriz.

step Komutu ile Döngülerde Adım Adım İlerleme

step komutu, bir fonksiyon çalıştırıldığında döngülerde tek tek adımları gösterir. Bu komut, döngünün tam olarak ne yaptığını izlemeyi sağlar. Önce print(number) ile bir sayıyı yazdırır, ardından harfleri yazdırmak için print(letter) ile devam eder, sonra tekrar sayıya döner ve bu şekilde döngü ilerler:

(Pdb) step
> /Users/sammy/looping.py(5)<module>()
-> def ic_ice_dongu():
(Pdb) step
> /Users/sammy/looping.py(11)<module>()
-> if __name__ == '__main__':
(Pdb) step
> /Users/sammy/looping.py(12)<module>()
-> ic_ice_dongu()
(Pdb) step
--Call--
> /Users/sammy/looping.py(5)ic_ice_dongu()
-> def ic_ice_dongu():
(Pdb) step
> /Users/sammy/looping.py(6)ic_ice_dongu()
-> for sayi in sayi_listesi:
(Pdb) step
> /Users/sammy/looping.py(7)ic_ice_dongu()
-> print(sayi)
(Pdb) step
500
> /Users/sammy/looping.py(8)ic_ice_dongu()
-> for harf in harf_listesi:
(Pdb) step
> /Users/sammy/looping.py(9)ic_ice_dongu()
-> print(harf)
(Pdb) step
x
> /Users/sammy/looping.py(8)ic_ice_dongu()
-> for harf in harf_listesi:
(Pdb) step
> /Users/sammy/looping.py(9)ic_ice_dongu()
-> print(harf)
(Pdb) step
y
> /Users/sammy/looping.py(8)ic_ice_dongu()
-> for harf in harf_listesi:
(Pdb)

Bunun aksine, next komutu fonksiyonu adım adım göstermeden tamamen çalıştırır. Mevcut oturumdan çıkmak için exit komutunu kullanarak çıkabilir ve hata ayıklayıcıyı yeniden başlatabilirsiniz:

$ python -m pdb looping.py

Şimdi next komutunu kullanarak devam edebiliriz:

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

Kodunuzu incelerken bir değişkene atanan değeri görmek isteyebilirsiniz. Bu, pp komutuyla yapılabilir. Bu komut, bir ifadeyi pprint modülünü kullanarak daha okunabilir bir biçimde yazdırır:

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

Pek çok pdb komutunun kısa yolları mevcuttur. Örneğin, step komutunun kısaltması s, next komutunun kısaltması n'dir. Son kullandığınız komutu tekrar çağırmak için istemde ENTER tuşuna basabilirsiniz.

###Durma Noktaları (Breakpoints) Daha büyük programlarla çalışırken, tüm programı adım adım geçmek yerine belirli fonksiyonlara veya satırlara odaklanmak isteyebilirsiniz. Bunun için break komutuyla durma noktaları ayarlayabilirsiniz. Program, belirtilen durma noktasına kadar çalıştırılır. Durma noktası eklendiğinde hata ayıklayıcı buna bir numara atar. Bu numaralar artan tam sayılardır ve durma noktalarıyla çalışırken bunlara başvurabilirsiniz. Durma noktalarını belirli satır numaralarına yerleştirmek için <program_dosyası>:<satır_no> sözdizimini kullanabilirsiniz:

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

Bir fonksiyonun tanımlandığı yere durma noktası yerleştirmek için:

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

Mevcut durma noktalarını kaldırmak için clear yazabilir ve ardından y tuşuna basabilirsiniz. Şartlı bir durma noktası ayarlayarak, belirli bir koşul sağlandığında durmasını sağlayabilirsiniz:

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

Eğer continue komutunu uygularsak, program number değişkeni 500'den büyük bir değere sahip olduğunda (örneğin, dış döngünün ikinci iterasyonunda 600 olduğunda) durur:

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

Mevcut durma noktalarını listelemek için break komutunu argümansız çalıştırabilirsiniz. Bu komut, durma noktalarının ayrıntılarını gösterir:

(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)

Bir durma noktasını devre dışı bırakmak için disable komutunu ve durma noktasının numarasını kullanabilirsiniz:

(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)

Bir durma noktasını tekrar etkinleştirmek için enable komutunu, tamamen kaldırmak için ise clear komutunu kullanabilirsiniz:

(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)

Durma Noktalarının Ek İşlevsellikleri: Geçici Durma Noktaları: İlk tetiklenişte otomatik olarak silinir. Örneğin: tbreak 3 Şartlı Durma Noktaları: Belirli bir koşul sağlandığında durur. Örneğin: break looping.py:7, number > 500 Durma Noktası Komutları: Belirli bir durma noktasında özel komutlar çalıştırabilirsiniz. Örneğin: commands 1

Program Akışını Değiştirme

Python hata ayıklayıcısı, programınızın akışını çalışma zamanında jump (atlama) komutuyla değiştirmenize olanak tanır. Bu komut, bazı kodların çalışmasını engellemek için ileri atlamanızı sağlar veya kodu yeniden çalıştırmak için geri gitmenize olanak tanır. Bu örnekte, sammy = 'sammy' dizisinin içindeki harfleri listeye ekleyen küçük bir program üzerinde çalışacağız: harf_listesi.py

def sammy_yazdir():
    sammy_listesi = []
    sammy = "sammy"
    for harf in sammy:
        sammy_listesi.append(harf)
        print(sammy_listesi)

if __name__ == "__main__":
    sammy_yazdir()

Programı her zamanki gibi python harf_listesi.py komutuyla çalıştırırsak, aşağıdaki çıktıyı alırız: Çıktı

['s']
['s', 'a']
['s', 'a', 'm']
['s', 'a', 'm', 'm']
['s', 'a', 'm', 'm', 'y']

Python hata ayıklayıcısını kullanarak, ilk döngüden sonra ileri atlamayı nasıl yapacağımızı gösterelim. Bunu yaparken, for döngüsünün kesildiğini fark edeceğiz: python -m pdb harf_listesi.py

> /Users/sammy/harf_listesi.py(1)<module>()
-> def sammy_yazdir():
(Pdb) list
  1  ->    def sammy_yazdir():
  2          sammy_listesi = []
  3          sammy = "sammy"
  4          for harf in sammy:
  5              sammy_listesi.append(harf)
  6              print(sammy_listesi)
  7      
  8      if __name__ == "__main__":
  9          sammy_yazdir()
 10      
 11      
(Pdb) break 5
Breakpoint 1 at /Users/sammy/harf_listesi.py:5
(Pdb) continue
> /Users/sammy/harf_listesi.py(5)sammy_yazdir()
-> sammy_listesi.append(harf)
(Pdb) pp harf
's'
(Pdb) continue
['s']
> /Users/sammy/harf_listesi.py(5)sammy_yazdir()
-> sammy_listesi.append(harf)
(Pdb) jump 6
> /Users/sammy/harf_listesi.py(6)sammy_yazdir()
-> print(sammy_listesi)
(Pdb) pp harf
'a'
(Pdb) disable 1
Disabled breakpoint 1 at /Users/sammy/harf_listesi.py:5
(Pdb) continue
['s']
['s', 'm']
['s', 'm', 'm']
['s', 'm', 'm', 'y']

Yukarıdaki hata ayıklama oturumunda, kodun devam etmesini engellemek için satır 5'e bir breakpoint (durma noktası) koyuyoruz, ardından kodu devam ettiriyor ve harf değişkeninin değerlerini daha iyi görmek için pretty-print komutuyla bazı değerleri yazdırıyoruz. Daha sonra, jump komutunu kullanarak 6. satıra atlıyoruz. Bu noktada, harf değişkeni 'a' değerini alıyor, ancak o değeri sammy_listesi listesine eklemiyoruz. Son olarak, breakpoint'i devre dışı bırakıp programı normal şekilde devam ettiriyoruz, böylece 'a' değeri sammy_listesilistesine eklenmemiş oluyor. Sonraki adımda, bu ilk oturumu sonlandırıp hata ayıklayıcıyı yeniden başlatabiliriz. Bu sefer, for döngüsünün ilk iterasyonunu yeniden çalıştıracağız:

> /Users/sammy/harf_listesi.py(1)<module>()
-> def sammy_yazdir():
(Pdb) list
  1  ->    def sammy_yazdir():
  2          sammy_listesi = []
  3          sammy = "sammy"
  4          for harf in sammy:
  5              sammy_listesi.append(harf)
  6              print(sammy_listesi)
  7      
  8      if __name__ == "__main__":
  9          sammy_yazdir()
 10      
 11      
(Pdb) break 6
Breakpoint 1 at /Users/sammy/harf_listesi.py:6
(Pdb) continue
> /Users/sammy/harf_listesi.py(6)sammy_yazdir()
-> print(sammy_listesi)
(Pdb) pp harf
's'
(Pdb) jump 5
> /Users/sammy/harf_listesi.py(5)sammy_yazdir()
-> sammy_listesi.append(harf)
(Pdb) continue
> /Users/sammy/harf_listesi.py(6)sammy_yazdir()
-> print(sammy_listesi)
(Pdb) pp harf
's'
(Pdb) disable 1
Disabled breakpoint 1 at /Users/sammy/harf_listesi.py:6
(Pdb) continue
['s', 's']
['s', 's', 'a']
['s', 's', 'a', 'm']
['s', 's', 'a', 'm', 'm']
['s', 's', 'a', 'm', 'm', 'y']

Yukarıdaki hata ayıklama oturumunda, 6. satıra bir breakpoint ekledik ve ardından kodu devam ettirerek 5. satıra geri atladık. Bu esnada, harf değişkeninin 's' değerinin sammy_listesi listesine iki kez eklendiğini görebiliyoruz. Daha sonra, 6. satırdaki breakpoint'i devre dışı bırakıp programı normal şekilde çalıştırıyoruz. Çıktıda, 's' değeri sammy_listesi listesine iki kez eklenmiş görünüyor. Bazı atlamalar, hata ayıklayıcı tarafından engellenir, özellikle belirli kontrol akışı ifadelerinden atlama yaparken. Örneğin, bir fonksiyona argümanlar tanımlanmadan atlayamazsınız veya bir try:except bloğunun ortasına atlayamazsınız. Ayrıca, bir finally bloğundan dışarı atlamak mümkün değildir. Python hata ayıklayıcısındaki "jump" komutu, programınızı hata ayıklarken akışını değiştirmenize olanak tanır. Bu, akış kontrolünü farklı amaçlar için değiştirip değiştiremeyeceğinizi görmek veya kodunuzdaki sorunları daha iyi anlamak için faydalıdır.

Yaygın pdb Komutları Tablosu

Aşağıda, Python hata ayıklayıcısını kullanırken aklınızda tutmanız gereken bazı faydalı pdb komutları ve kısa formaları yer almaktadır:


Komut Kısa Form Ne Yapar
args a Mevcut fonksiyonun argüman listesini yazdırır
break b Programın belirli bir satırında durma noktası oluşturur (parametre gerektirir)
continue c veya cont Program yürütmesini devam ettirir
help h Komutlar listesi veya belirtilen komut için yardım sağlar
jump j Bir sonraki yürütülecek satırı ayarlar
list l Mevcut satır etrafındaki kaynak kodunu yazdırır
next n Mevcut fonksiyonda bir sonraki satıra kadar devam eder
step s Mevcut satırı çalıştırır ve ilk fırsatta durur
pp pp İfadenin değerini güzel bir şekilde yazdırır
quit veya exit q Programı sonlandırır
return r Mevcut fonksiyon dönene kadar devam eder


Hata ayıklayıcı ile ilgili komutlar ve nasıl çalıştığı hakkında daha fazla bilgiye Python hata ayıklayıcı dokümantasyonundan ulaşabilirsiniz.

Sonuç

Hata ayıklama, yazılım geliştirme projelerinin önemli bir aşamasıdır. Python hata ayıklayıcısı pdb, yazdığınız Python programlarının her biriyle kullanabileceğiniz etkileşimli bir hata ayıklama ortamı sağlar. Programınızı durdurma, değişkenlerinizin değerlerini inceleme ve program yürütmesini adım adım takip etme özellikleriyle, programınızın ne yaptığını daha iyi anlayabilir ve mantıksal hataları bulabilir veya bilinen sorunları çözebilirsiniz.


Lisa Tagliaferri tarafından yazılan How To Use the Python Debugger Program makalesinin düzenlenmiş çevirisi.


Daha Fazla Oku:


Bu Makaleyi Paylaş

Yorumlar

yorum Yap