Կարգավորվող բացառություններ

Ծրագրի իրագործման ժամանակ կարող են սխալներ ի հայտ գալ, իսկ 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) առկայություն: Մուտքագրված անունը պետք է ճշտորեն համընկնի տվյալների բազայում նշված անվան հետ:
 

Constraints

Time limit: 2 seconds

Memory limit: 512 MB

Output limit: 1 MB

To check your solution you need to sign in
Sign in to continue