Ծրագրի իրագործման ժամանակ կարող են սխալներ ի հայտ գալ, իսկ Python-ում բացառությունները կիրառվում են որպես սխալներին արձագանքելու միջոց։ Python-ն ունի բազմաթիվ ներկառուցված բացառություններ, օրինակ՝ IndexError-ը, երբ փորձում եք հասանելիություն ստանալ ինդեքսին, որը գոյություն չունի ցուցակում, կամ TypeError-ը, երբ փորձում եք գործողություն կատարել այնպիսի տեսակի վրա, որը տվյալ դեպքում կիրառելի չէ: Երբեմն, սակայն, կարող է օգտակար լինել սահմանել մեր սեփական բացառությունները: Սա մեզ թույլ է տալիս գրել սխալը նկարագրող օգտակար հաղորդագրություններ և աշխատել այնպիսի դեպքերի հետ, երբ ներկառուցված բացառությունները կիրառելի չեն: Կարգավորվող բացառությունները ստեղծվում են՝ սահմանելով նոր class, որը ժառանգում է ներկառուցված Exception class-ից կամ դրա ենթադասերից մեկից:
Դիտարկենք մի ծրագիր, որն աշխատում է տեսական գրադարանային համակարգի հետ։ Այս համակարգում օգտվողին չպետք է թույլ տրվի միաժամանակ ստուգել 5-ից ավելի գիրք: Ահա թե ինչպես կարող ենք տվյալ դեպքի համար ստեղծել կարգավորվող բացառություն.
class TooManyBooksError(Exception): # Define a new exception class
pass
def checkout_books(user, num_books):
if num_books > 5:
# Raise an exception if the user tries to check out more than 5 books
raise TooManyBooksError('You cannot check out more than 5 books at a time.') # Raise our custom exception
# Otherwise, add the books to the user's account.
user.books += num_books
Վերոնշյալ օրինակում, եթե օգտատերը փորձի միաժամանակ ստուգել 5-ից ավելի գիրք, մեր TooManyBooksError-ը raise կիրականացվի սխալի վերաբերյալ հատուկ հաղորդագրությամբ: Եթե բացառություն չկա, ծրագիրը կկանգնի, և վահանակի վրա կտպվի սխալը նկարագրող հաղորդագրությունը:
Մենք կարող ենք «բռնել» այս բացառությունը այնպես, ինչպես ներկառուցված բացառությունները՝ օգտագործելով try / except բլոկները.
try:
checkout_books(user, 7) # Try to check out 7 books.
except TooManyBooksError as e: # Catch our custom exception
print(e) # Print the error message.
Եթե checkout_books(user, 7) տողը raise է անում TooManyBooksError, ծրագիրը «կբռնի» այն և կտպի մեր սխալի հաղորդագրությունը 'You cannot check out more than 5 books at a time.': Այսպիսով, մենք սահուն կերպով կարգավորում ենք սխալը, իսկ ծրագիրը շարունակում է աշխատել:
Ինչպես ցանկացած այլ class-ի դեպքում, մենք բացառության class-ին կարող ենք մեթոդներ ավելացնել: Օրինակ, եկե՛ք ավելացնենք մի մեթոդ, որը հաշվում է, թե օգտվողը քանի գիրք պետք է վերադարձնի, ցանկալի քանակով գրքեր վերցնելու համար.
class TooManyBooksError(Exception):
def __init__(self, attempted, limit=5, checked_out=0):
self.attempted = attempted
self.limit = limit
self.checked_out = checked_out
self.message = f'You tried to check out {self.attempted} books, but the limit is {self.limit} books.'
super().__init__(self.message)
def books_to_return(self):
return self.checked_out + self.attempted - self.limit
Բացառությունը «բռնելուց» հետո մենք կարող ենք կիրառել հետևյալ մեթոդը.
try:
checkout_books(user, 7)
except TooManyBooksError as e:
print(e) # You tried to check out 7 books, but the limit is 5 books.
print(f'You need to return {e.books_to_return()} books.') # You need to return 2 books.
Այսպիսով, կարգավորվող բացառությունները կարող են ունենալ իրենց ատրիբուտներն ու մեթոդները, ինչի շնորհիվ դրանք դառնում են հզոր գործիք՝ սխալները կարգավորելու համար, ընդ որում՝ կարգավորումը կատարվում է այնպես, որ համապատասխանի ձեր ծրագրի պահանջներին և կարիքներին։
Առաջադրանք․ տարիքի տվյալների բազա
Մի քաղաքում, որտեղ բոլորը ճանաչում են միմյանց, տեղական իշխանությունները փորձում են տարիքի ստուգման համակարգ ներդնել քաղաքային վայրերում՝ բարերում, ակումբներում և թատրոններում: Անհրաժեշտ է ծրագիր, որը, ունենալով մարդկանց տարիքի մասին տեղեկատվությունը, կընդունի անունները և կվերադարձնի տվյալ մարդու տարիքը:
Մուտքը կառավարվում է ավտոմատ կերպով: Դուք պետք է ստեղծեք find_age(name) ֆունկցիան, որը, ունենալով անունը, կվերադարձնի մարդու տարիքը:
Սակայն քաղաքի տվյալների բազայում ոչ բոլորի անունները կան: Ուստի, եթե ծրագիրը տվյալների բազայում չի կարողանում գտնել որևէ անուն, այն պետք է raise անի հատուկ բացառություն, որը կոչվում է NameNotFoundError, և տպի համապատասխան սխալի մասին հաղորդագրություն՝ {name} not found in the database։
Մուտք
Ելք
5
Alice - 24
Bob - 32
Charlie - 21
Daisy - 27
Edgar - 30
Edgar
Edgar - 30
5
Alice - 24
Bob - 32
Charlie - 21
Daisy - 27
Edgar - 30
George
NameNotFoundError: George not found in the database.
Նշում. անվան և տարիքի դեպքում մեծատառերն ու փոքրատառերը կարևոր են։ Հնարավոր է նաև բացատների (space) առկայություն: Մուտքագրված անունը պետք է ճշտորեն համընկնի տվյալների բազայում նշված անվան հետ: