İçeriğe geç
Educora
Orta15 dk11 / 42

Hata yönetimi: try ve except

Programının çökmesini engelle: istisnaları tanı, try/except/else/finally ile yakala ve raise ile kendin oluştur.

Kendini test et
Bu derste öğreneceklerin
  • En sık karşılaşılan istisnaları tanımak
  • try ve except ile hatayı yakalayıp programı sürdürmek
  • else, finally ve raise kullanmak

Bir hesap makinesi programı yazdın. Kullanıcı sayı yerine “on iki” yazıyor ya da sıfıra bölüyor ve program kırmızı bir hata mesajıyla duruyor. Kimse böyle bir programı sevmez! İyi bir program hatalara hazırlıklıdır: sorunu tanır, kullanıcıya açıkça anlatır ve çalışmaya devam eder.

İstisna nedir?

İki tür hata vardır. Sözdizimi hataları (SyntaxError) kodun yazılışındaki hatalardır ve program hiç başlamaz. Kod doğru yazılmış ama çalışırken bir şeyler ters gidiyorsa Python bir istisna (exception) oluşturur. İstisna yakalanmazsa program durur ve Python bir “traceback”, yani hata raporu gösterir:

Text
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(10 / count)
ZeroDivisionError: division by zero
İstisnaNe zaman oluşurÖrnek
ValueErrortür doğru ama değer uygun değilint('abc')
TypeErrorişlem bu tür için mümkün değil'5' + 5
ZeroDivisionErrorsıfıra bölme10 / 0
IndexErrorböyle bir indeks yok[1, 2][5]
KeyErrorsözlükte böyle bir anahtar yok{}['a']
NameErrorbu adda bir değişken yokprint(scor)

try ve except

Hata verebilecek kodu bir try bloğuna koyarız. Bir istisna oluşursa Python try bloğunun geri kalanını atlar ve uygun except bloğuna geçer. Ardından program normal şekilde devam eder.

Python
text = 'abc'
try:
    number = int(text)
    print('Number:', number)
except ValueError:
    print('That is not a number!')
print('The program continues.')
▸ Beklenen çıktı
That is not a number!
The program continues.
text değişkenine '25' ver ve sonucu karşılaştır.

Bir try için birden fazla except yazılabilir; her biri kendi istisna türünü yakalar. except ... as e yazımı istisnanın kendisini e değişkenine kaydeder; onu yazdırırsan Python'un açıklamasını görürsün.

Python
def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        print('Cannot divide by zero!')
    except TypeError as e:
        print('Wrong type:', e)
    return None

print(safe_divide(10, 2))
print(safe_divide(5, 0))
print(safe_divide(5, 'x'))
▸ Beklenen çıktı
5.0
Cannot divide by zero!
None
Wrong type: unsupported operand type(s) for /: 'int' and 'str'
None

else ve finally

  • else bloğu yalnızca try hatasız tamamlandığında çalışır; başarılı sonuçla yapılacak işi oraya yaz.
  • finally bloğu hata olsa da olmasa da her zaman çalışır. Genellikle işi toparlamak için kullanılır: dosyayı kapatmak, mesaj yazmak.
Python
for value in ['42', 'seven']:
    try:
        n = int(value)
    except ValueError:
        print(f'{value}: not a number')
    else:
        print(f'{value}: doubled is {n * 2}')
    finally:
        print('checked', value)
▸ Beklenen çıktı
42: doubled is 84
checked 42
seven: not a number
checked seven

raise: kendi istisnanı oluşturmak

Bazen Python için her şey yolundadır ama senin programın için değil: örneğin yaş negatif olamaz. Böyle durumlarda raise ile istisnayı kendin oluşturabilirsin. Aşağıdaki kod bir kullanıcının cevaplarını taklit eder ve ilk geçerli yaşı kabul eder:

Python
answers = ['abc', '-3', '14']
for answer in answers:
    try:
        age = int(answer)
        if age <= 0:
            raise ValueError('age must be positive')
    except ValueError as e:
        print(f'Bad input {answer}: {e}')
    else:
        print('Accepted age:', age)
        break
▸ Beklenen çıktı
Bad input abc: invalid literal for int() with base 10: 'abc'
Bad input -3: age must be positive
Accepted age: 14
Alıştırma

data listesindeki dizileri int() ile sayıya çevir ve topla. Çevrilemeyen bir elemanda program durmamalı: hatayı try/except ValueError ile yakala ve Skipped: ile birlikte o elemanı yazdır. En sonda Total: ve toplamı yazdır.

Alıştırma · Python
data = ['12', 'seven', '30', '4.5', '8']
total = 0
# for each item: try to add int(item) to total,
# on ValueError print Skipped: and the item
# print Total: and total
▸ Beklenen çıktı
Skipped: seven
Skipped: 4.5
Total: 50
Alıştırma

Depoda 100 defter var. sell(stock, count) fonksiyonunu yaz: count sıfır ya da negatifse ValueError('count must be positive'), depodakinden fazlaysa ValueError('not enough in stock') fırlatsın, aksi hâlde kalan sayıyı döndürsün. Başlangıç kodundaki döngü her satışı try/except ile dener; onu değiştirme.

Alıştırma · Python
# define sell(stock, count) here

stock = 100
for count in [30, -5, 90, 50]:
    try:
        stock = sell(stock, count)
        print('Sold', count, '- left:', stock)
    except ValueError as e:
        print('Error:', e)
▸ Beklenen çıktı
Sold 30 - left: 70
Error: count must be positive
Error: not enough in stock
Sold 50 - left: 20

Önemli noktalar

  • İstisna, program çalışırken oluşan bir hatadır; yakalanmazsa program durur.
  • try riskli kodu içerir, except ise belirli bir istisnayı yakalar.
  • else yalnızca hata olmadığında, finally ise her zaman çalışır.
  • raise ile kendi istisnanı oluşturabilirsin: raise ValueError('...').
  • Traceback'in son satırı istisnanın türünü ve nedenini gösterir.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
int('hello') hangi istisnayı oluşturur?