Məzmuna keç
Educora
Orta15 dəq11 / 42

Xətaların idarə olunması: try və except

Proqramın xəta ilə dayanmasının qarşısını al: istisnaları tanı, try/except/else/finally ilə tut və raise ilə özün yarat.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Ən çox rast gəlinən istisnaları tanımaq
  • try və except ilə xətanı tutub proqramı davam etdirmək
  • else, finally və raise operatorlarından istifadə etmək

Kalkulyator proqramı yazmısan. İstifadəçi ədəd əvəzinə «on iki» yazır və ya sıfıra bölür — proqram qırmızı xəta mesajı ilə dayanır. Heç kim belə proqramı sevmir! Yaxşı proqram səhvə hazır olur: problemi tanıyır, istifadəçiyə aydın izah verir və işini davam etdirir.

İstisnalar nədir?

Xətaların iki növü var. Sintaksis xətaları (SyntaxError) kodun yazılışında olur və proqram heç başlamır. Kod düzgün yazılıb, amma icra zamanı nəsə alınmırsa, Python istisna (exception) yaradır. İstisna tutulmasa, proqram dayanır və Python «traceback» — xəta hesabatı göstərir:

Text
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(10 / count)
ZeroDivisionError: division by zero
İstisnaNə vaxt yaranırNümunə
ValueErrorqiymətin tipi düzdür, amma özü yararsızdırint('abc')
TypeErrorəməl bu tip üçün mümkün deyil'5' + 5
ZeroDivisionErrorsıfıra bölmə10 / 0
IndexErrorbelə indeks yoxdur[1, 2][5]
KeyErrorlüğətdə belə açar yoxdur{}['a']
NameErrorbelə adda dəyişən yoxdurprint(scor)

try və except

Xəta verə biləcək kodu try blokuna yerləşdiririk. İstisna yaranarsa, Python try-ın qalanını buraxır və uyğun except blokuna keçir. Bundan sonra proqram adi qaydada davam edir.

Python
text = 'abc'
try:
    number = int(text)
    print('Number:', number)
except ValueError:
    print('That is not a number!')
print('The program continues.')
▸ Gözlənilən nəticə
That is not a number!
The program continues.
text dəyişəninə '25' ver və nəticəni müqayisə et.

Bir try üçün bir neçə except yazmaq olar — hər biri öz istisna tipini tutur. except ... as e yazılışı istisnanın özünü e dəyişəninə yazır, onu çap etsən, Python-un izahı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'))
▸ Gözlənilən nəticə
5.0
Cannot divide by zero!
None
Wrong type: unsupported operand type(s) for /: 'int' and 'str'
None

else və finally

  • else bloku yalnız try xətasız başa çatdıqda icra olunur — uğurlu nəticə ilə işi ora yaz.
  • finally bloku həmişə icra olunur — xəta olsa da, olmasa da. Adətən orada işi yekunlaşdırırlar: faylı bağlayır, mesaj yazırlar.
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)
▸ Gözlənilən nəticə
42: doubled is 84
checked 42
seven: not a number
checked seven

raise: öz istisnanı yaratmaq

Bəzən Python üçün hər şey qaydasındadır, amma sənin proqramın üçün yox: məsələn, yaş mənfi ola bilməz. Belə hallarda raise ilə istisnanı özün yarada bilərsən. Aşağıdakı kod istifadəçinin cavablarını təqlid edir və ilk düzgün yaşı qəbul edir:

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
▸ Gözlənilən nəticə
Bad input abc: invalid literal for int() with base 10: 'abc'
Bad input -3: age must be positive
Accepted age: 14
Tapşırıq

data siyahısındakı sətirləri int() ilə ədədə çevir və topla. Çevrilə bilməyən elementdə proqram dayanmamalıdır: xətanı try/except ValueError ilə tut və Skipped: sözündən sonra həmin elementi çap et. Sonda Total: və cəmi çap et.

Tapşırıq · 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
▸ Gözlənilən nəticə
Skipped: seven
Skipped: 4.5
Total: 50
Tapşırıq

Anbarda 100 dəftər var. sell(stock, count) funksiyasını yaz: count sıfır və ya mənfidirsə ValueError('count must be positive'), anbardakından çoxdursa ValueError('not enough in stock') qaldırsın, əks halda qalan sayı qaytarsın. Başlanğıc kodundakı dövr hər satışı try/except ilə yoxlayır — onu dəyişmə.

Tapşırıq · 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)
▸ Gözlənilən nəticə
Sold 30 - left: 70
Error: count must be positive
Error: not enough in stock
Sold 50 - left: 20

Əsas fikirlər

  • İstisna icra zamanı yaranan xətadır; tutulmasa, proqram dayanır.
  • try riskli kodu saxlayır, except isə konkret istisnanı tutur.
  • else yalnız xəta olmadıqda, finally isə həmişə icra olunur.
  • raise ilə öz istisnanı yaratmaq olar: raise ValueError('...').
  • Traceback-in son sətri istisnanın tipini və səbəbini göstərir.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
int('hello') hansı istisnanı yaradır?