Användardefinierade undantag i Python med exempel
Användardefinierade undantag skapas genom att definiera en ny klass som ärver från Pythons inbyggda undantag klass eller en av dess underklasser. Genom att göra detta kan vi skapa anpassade felmeddelanden och hantera specifika fel på ett sätt som är vettigt för vår applikation.
Steg för att skapa och använda användardefinierade undantag
Följ dessa steg för att skapa och använda användardefinierade undantag i Python:
- Definiera en ny undantagsklass: Skapa en ny klass som ärver från Exception eller någon av dess underklasser.
- Höj undantaget: Använd raise-satsen för att höja det användardefinierade undantaget när ett specifikt tillstånd uppstår.
- Hantera undantaget: Använd try-except-block för att hantera det användardefinierade undantaget.
Exempel: I det här exemplet skapar vi ett anpassat undantag InvalidAgeError för att säkerställa att åldersvärdena faller inom ett giltigt intervall (0–120).
Python # Step 1: Define a custom exception class class InvalidAgeError ( Exception ): def __init__ ( self age msg = 'Age must be between 0 and 120' ): self . age = age self . msg = msg super () . __init__ ( self . msg ) def __str__ ( self ): return f ' { self . age } -> { self . msg } ' # Step 2: Use the custom exception in your code def set_age ( age ): if age < 0 or age > 120 : raise InvalidAgeError ( age ) else : print ( f 'Age set to: { age } ' ) # Step 3: Handling the custom exception try : set_age ( 150 ) # This will raise the custom exception except InvalidAgeError as e : print ( e )
Produktion
150 -> Age must be between 0 and 120
Förklaring:
- InvalidAgeError-klassen ärver från Exception. Den definierar en __varm__ metod för att acceptera ålder och budskap.
- Metoden __str__ returnerar en läsbar strängrepresentation av felet.
- I set_age() om åldern är utanför det giltiga intervallet (0–120) höjs undantaget.
- Blocket try-except fångar undantaget och skriver ut felmeddelandet.
Anpassa undantagsklasser
När vi skapar ett anpassat undantag underklassar vi Pythons inbyggda undantagsklass (eller en underklass som ValueError TypeError etc.). Vi kan sedan lägga till våra egna attributmetoder eller anpassad logik för att göra vårt undantag mer informativt.
Vi kan också förbättra anpassade undantag genom att lägga till extra attribut eller åsidosättande metoder.
Exempel: Här förbättrar vi InvalidAgeError genom att lägga till en felkod och anpassa felmeddelandet.
Python class InvalidAgeError ( Exception ): def __init__ ( self age msg = 'Age must be between 0 and 120' error_code = 1001 ): self . age = age self . msg = msg self . error_code = error_code super () . __init__ ( self . msg ) def __str__ ( self ): return f '[Error Code { self . error_code } ] { self . age } -> { self . msg } ' try : set_age ( 150 ) # This will raise the custom exception except InvalidAgeError as e : print ( e )
Produktion
[Error Code 1001] 150 -> Age must be between 0 and 120
Förklaring:
- InvalidAgeError har nu ett ytterligare attribut error_code.
- Metoden __str__ åsidosätts för att visa både felkoden och åldern.
- När set_age(150) exekveras höjs undantaget och fångas i try-except-blocket.
- Det anpassade felmeddelandet skrivs ut vilket gör felet mer beskrivande.
Använda standardundantag som basklass
Ibland istället för att direkt ärva från Exception kan vi skapa ett anpassat undantag genom att underklassa ett standardundantag såsom RuntimeError ValueError etc. Detta är användbart när ditt anpassade undantag ska behandlas som en specifik typ av fel.
Exempel: Det här exemplet visar hur man skapar ett anpassat undantag NetworkError genom att ärva från RuntimeError som är ett standardinbyggt undantag.
Python # NetworkError has base RuntimeError and not Exception class NetworkError ( RuntimeError ): def __init__ ( self arg ): self . args = ( arg ) # store as tuple try : raise NetworkError ( 'Connection failed' ) except NetworkError as e : print ( e . args )
Produktion
('Connection failed') Förklaring:
- NetworkError ärver från RuntimeError som är en inbyggd undantagstyp.
- När meddelandet höjs lagras det i args-attributet som en tupel.
- Undantaget fångas upp och dess lagrade argument visas.
Exempel i verkliga världen: Felaktigt e-postmeddelande
Här är ett enkelt exempel där vi tar upp ett anpassat undantag om e-postadressen inte är giltig:
Python class InvalidEmailError ( Exception ): def __init__ ( self email msg = 'Invalid email format' ): self . email = email self . msg = msg super () . __init__ ( self . msg ) def __str__ ( self ): return f ' { self . email } -> { self . msg } ' def set_email ( email ): if '@' not in email : raise InvalidEmailError ( email ) print ( f 'Email set to: { email } ' ) try : set_email ( 'userexample.com' ) except InvalidEmailError as e : print ( e )
Produktion
userexample.com -> Invalid email format
Förklaring:
- En ny undantagsklass InvalidEmailError har definierats för att validera e-postadresser.
- Om det givna e-postmeddelandet inte innehåller '@' tas undantaget upp.
- Försök-utom-blocket fångar felet och skriver ut det formaterade meddelandet.
När ska man använda användardefinierade undantag?
Användardefinierade undantag bör övervägas i följande scenarier:
- Representerar specifika fel i en applikation (t.ex. InvalidAgeError DatabaseConnectionError).
- Ger tydligare och mer beskrivande felmeddelanden.
- Hantera en grupp av relaterade fel separat med hjälp av except.
Genom att använda användardefinierade undantagsprogram blir mer läsbara underhållbara och lättare att felsöka.
Förslag på frågesport Redigera frågesport 3 frågorVad händer om ett användardefinierat undantag ärver från RuntimeError istället för Exception?
- A
Den kan inte fångas med annat än
- B
Det blir ett okontrollerat undantag
- C
Det behandlas som ett körtidsrelaterat fel av hanterare
- D
Den förlorar anpassade attribut
Genom att ärva från RuntimeError kan det hanteras som ett körtidsfel såväl som ett anpassat.
Varför används super().__init__(self.msg) vanligtvis i anpassade undantagsklasser?
- A
För att förhindra flerfaldigt arv
- B
För att korrekt initiera grundklassen Exception
- C
För att åsidosätta spårningen
- D
För att automatiskt höja undantaget
Att anropa super() säkerställer att basundantaget initieras korrekt med meddelandet.
Vad kommer att skrivas ut om ett anpassat undantag åsidosätter __str__() och skrivs ut inuti förutom?
- A
Den åsidosatta strängrepresentationen
- B
Minnesadress för undantaget
- C
Endast klassnamnet
- D
Ingenting om inte repr() används
print(e) anropar __str__() för undantagsobjektet.
Frågesport avslutade framgångsrikt ditt resultat: 2 /3 Noggrannhet: 0 % Logga in för att se förklaring 1 /3 1 /3 < Previous Nästa >