Presentation is loading. Please wait.

Presentation is loading. Please wait.

George Mason University

Similar presentations


Presentation on theme: "George Mason University"— Presentation transcript:

1 George Mason University
CS 112 Intro to Programming Exceptions George Mason University

2 Exception Handling: Basic Syntax
try: #watch for exceptions here try_suite except: #exception handling code except_suite A piece of code that is potential to crash in runtime 2

3 Exceptions Hierarchy BaseException +-- KeyboardInterrupt +-- Exception +-- ArithmeticError | ZeroDivisionError +-- EnvironmentError | IOError +-- EOFError +-- LookupError | IndexError | KeyError +-- NameError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError There are many exception classes organized into a hierarchy → using inheritance (parent and child class relationships) (found at ) Whenever a runtime error occur in ‘try’, the ‘except’ will handle this specific exception (event)

4 Validating Input Loop continues to execute, raising and handling exceptions, until user complies. e4.py need_input = True while need_input: x = eval(input("#: ")) need_input = False print ("successfully got x: "+str(x))

5 Validating Input Exception1 Exception2 e4.py
Loop continues to execute, raising and handling exceptions, until user complies. e4.py need_input = True while need_input: try: x = eval(input("#: ")) need_input = False except Exception as e: print(e) print ("successfully got x: "+str(x)) demo$ python3 e4.py #: 5 successfully got x: 5 #: asdf name 'asdf' is not defined #: 3/0 division by zero Exception1 Exception2

6 Exception Handling There are three basic choices when handling exceptions: handle it defer it up the calling chain do both: handle it, but also defer it to the caller. Example: if method A calls method B, and then B calls method C, and C raises an exception: C can handle it C can defer it to B (the caller of C) → B, and in turn, A, then have the same choices C can handle it and then re-raise it 6

7 Exception Handling Propagate (report the error) I will handle it
Method A (Function A) Method B Method C Exception (error) I will handle it 7

8 Validating Input Exception1 Exception2 e4.py
Loop continues to execute, raising and handling exceptions, until user complies. e4.py need_input = True while need_input: try: x = eval(input("#: ")) need_input = False except Exception as e: print(e) print ("successfully got x: "+str(x)) demo$ python3 e4.py #: 5 successfully got x: 5 #: asdf name 'asdf' is not defined #: 3/0 division by zero Exception1 Exception2

9 Exception Handling I will handle it defer Ouch! Method A Method B
Method C Exception I will handle it defer Ouch! 9

10 Deferring Exceptions exception raised in buggy crashes (propagates) out to whatever called it: main, in this case. main catches the exception. demo$ python3 e12.py #? 10 0.5 #? 0 sadly, we cannot do zero division. #? asdf Traceback … ValueError… e12.py def buggy (): x = int(input("#? ")) return 5/x def main(): try: print(buggy()) except ZeroDivisionError as e: print("sadly, we cannot do zero division.") main() 10

11 Exception Handling Propagate (report the error) I will handle it defer
Method A Method B Method C Exception I will handle it defer Ouch! 11

12 Exception Handling Defer the rest I will handle some Defer the rest
Method A Method B Method C Exception Defer the rest I will handle some Defer the rest I will handle some 12

13 Deferring Some Exceptions
ValueErrors caught in buggy. ZeroDivisionErrors propagated to main, caught there. TypeErrors propagated all the way, crashing entire program. demo$ python3 e13.py #? 3 #? "hello" didn't get an int! #? 0 sadly, we cannot do zero division. demo$ #? (1,2,3) Traceback … TypeError… e13.py def buggy (): try: x = int(eval(input("#? "))) return 5/x except ValueError as e: print ("didn't get an int!") return 0 def main(): print(buggy()) except ZeroDivisionError as zde: print("sadly, we cannot do zero division.") main() 13

14 Deferring - another example
KeyError handled in find() ZeroDivisionError deferred in find(), then handled in main() ValueErrors unhandled. demo$ python3 e14.py #? 6 a #? 4 red herring #? 0 sadly, we cannot do zero division. #? asdf Traceback…ValueError… e14.py def find(): try: d = {1:'a',2:'b',3:'c'} v = int(input("#? ")) return d[6/v] except KeyError as verr: return "red herring" def main(): print(find()) except ZeroDivisionError as zde: print("sadly, we cannot do zero division.") main() 14

15 If the exception is handled by C, then B will not notice it
Exception Handling Method A Method B Method C Exception Defer the rest Login bank account I will handle some Count failed times Defer the rest Verify the password I will handle some If the exception is handled by C, then B will not notice it 15

16 After the exception is handled by C, we will manually inform B
Exception Handling Method A Method B Method C Exception Login bank account I will handle it, too Count failed times Re-raise Verify the password I will handle it After the exception is handled by C, we will manually inform B 16

17 Raising Exceptions We can generate an exception on purpose (and hopefully catch it somewhere else!) done with a raise statement, which needs an expression of some Exception type. This usually means calling a constructor (__init__). Examples: raise Exception("boo!") raise ArithmeticError ("this doesn't add up!") raise ValueError("needed a positive number") except IOError as e: print ("catching it, re-raising it.") raise e

18 Build-in exception, everyone know what they means
Exceptions Hierarchy BaseException +-- KeyboardInterrupt +-- Exception +-- ArithmeticError | ZeroDivisionError +-- EnvironmentError | IOError +-- EOFError +-- LookupError | IndexError | KeyError +-- NameError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError There are many exception classes organized into a hierarchy → using inheritance (parent and child class relationships) (found at ) Build-in exception, everyone know what they means

19 Raising Exceptions Reusing/raising a few specific exception types is useful: Exception for general issues (but a bit vague) TypeError, when the supplied arg. was the wrong type ValueError when your code only should be run on some batch of values and the wrong one was given Any of them can be reused if it suits your purpose, just call their constructor (see examples on previous slide) Then you can raise them and catch them as before. → but you can also make brand new types of exceptions!

20 Re-raising the Same Exception
We can directly re-raise the caught exception object. To force this exception propagate, since by default exception only get handled once No need to construct an exception value-we already have an exception object. note the quotes! e15.py def get_input(): try: return float(eval(input("#: "))) except ValueError as e: print("in get_input: "+str(e)) raise e def main(): print( get_input()) except (TypeError, ValueError) as e: print ("in main: "+str(e)) main() demo$ python3 e16.py #: 'a' in get_input: could not convert string to float: 'a' in main: could not convert string to float: 'a' 20

21 Re-raising Another Exceptions
Initialize an exception ourselves We want to customized the error information to the caller demo$ python3 e15.py #: 'asdf' in get_input: could not convert string to float: 'asdf' in main: ERR #: (1,2,3) in main: float() argument must be a string or a number #: asdf Traceback…NameError… e15.py def get_input(): try: return float(eval(input("#: "))) except ValueError as e: print("in get_input: "+str(e)) raise (ValueError("ERR")) def main(): print( get_input()) except (TypeError, ValueError) as e: print ("in main: "+str(e)) main() note the quotes! 21

22 After the exception is handled by C, we will manually inform B
Exception Handling Method A Method B Method C Exception Login bank account I will handle it, too Count failed times Re-raise Verify the password I will handle it After the exception is handled by C, we will manually inform B 22

23 Exceptions and Classes
Did you find initialization of an exception looks the same as initialization of an object of a class? Actually exceptions are just a kind of class: e15.py def get_input(): try: return float(eval(input("#: "))) except ValueError as e: print("in get_input: "+str(e)) raise (ValueError("ERR")) def main(): print( get_input()) except (TypeError, ValueError) as e: print ("in main: "+str(e)) main() Class (web page) Exception Driven by user behavior Driven by runtime error Click a link or button Through out an exception Open a new web page Initialize an exception object

24 Exceptions Hierarchy Inheritance relations
BaseException +-- KeyboardInterrupt +-- Exception +-- ArithmeticError | ZeroDivisionError +-- EnvironmentError | IOError +-- EOFError +-- LookupError | IndexError | KeyError +-- NameError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError There are many exception classes organized into a hierarchy → using inheritance (parent and child class relationships) (found at ) Inheritance relations We usually define customized exception as child class of build-in ones

25 User-Defined Exceptions
We can create our own types of exceptions. They can be raised, propagated, and caught just like any other exception types. e10.py class Disallowed (Exception): def __init__(self, value): self.value = value 25

26 User-Defined Exceptions
e11.py from e10 import Disallowed try: x = int(input("#? ")) if x==13: raise Disallowed("that's unlucky!") print(x*10) except Disallowed as dis: print("uhoh: "+dis.value) except Exception as e: print(e) raise keyword used with a call to our exception's constructor except-block used with our new type of exception demo$ python3 e11.py #? 5 50 #? 13 uhoh: that's unlucky! #? asdf invalid literal for int() with base 10: 'asdf' Raise an exception just like: If want to trigger this event, then raise this exception 26

27 Example: using exception handling in classes
A class can use exceptions within its methods, just like we've done before. e17.py class LongNameException(Exception): def __init__(self, text="too long!"): self.text = text class Artist(object): def __init__(self, name="None"): self.__name = name def set_name (self, name): try: if (len(name))>10: raise LongNameException() else: except LongNameException as e: print(e.text) demo$ python3 -i e17.py >>> alice = Artist() >>> alice.set_name("Alice Cooper") too long!

28 Example: using instance variables in exceptions
e18.py class LongNameException(Exception): def __init__(self, text="too long!", data=""): self.text = text self.data = data class Artist(object): def __init__(self, name="None"): self.__name = name def set_name (self, name): try: if (len(name))>10: raise LongNameException(data=(len(name))) else: except LongNameException as e: print(e.text+" ("+str(e.data)+")") demo$ python3 -i e18.py >>> alice = Artist() >>> alice.set_name("Alice Cooper") too long! (12) Our exceptions are objects, and they can have/use instance variables like data.


Download ppt "George Mason University"

Similar presentations


Ads by Google