#Chapter 8 异常 Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. #8.1 什么是异常 >>> 1/0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero #8.2 按自己的方式出错 #8.2.1 raise语句 >>> raise Exception Traceback (most recent call last): File "<stdin>", line 1, in <module> Exception >>> raise Exception('hyperdrive overload') Traceback (most recent call last): File "<stdin>", line 1, in <module> Exception: hyperdrive overload >>> import exceptions >>> dir(exceptions) ['ArithmeticError', 'AssertionError', 'AttributeError', ...] >>> raise ArithmeticError Traceback (most recent call last): File "<stdin>", line 1, in <module> ArithmeticError #8.2.2 自定义异常类 >>> class SomeCustomException(Exception): pass ... #8.3 捕捉异常 try: x=input('Enter the first number: ') y=input('Enter the second number: ') print x/y except ZeroDivisionError: print "The second number can't be zero!" #打开或关闭屏蔽 class MuffleCalculator: muffled = False def calc(self, expr): try: return eval(expr) except ZeroDivisionError: if self.muffled: print 'Division by zero is illegal' else: raise calculator=MuffleCalculator() print calculator.calc('10/2') #print calculator.calc('10/0') # No muffling #5 #Traceback (most recent call last): # File "tta.py", line 14, in <module> # print calculator.calc('10/0') # No muffling # File "tta.py", line 5, in calc # return eval(expr) # File "<string>", line 1, in <module> #ZeroDivisionError: integer division or modulo by zero calculator.muffled=True calculator.calc('10/0') #Division by zero is illegal #8.4 不止一个 except 语句 try: x=input('Enter the first number: ') y=input('Enter the second number: ') print x/y except ZeroDivisionError: print "The second number can't be zero!" except TypeError: print "That wasn't a number, was it?" #8.5 用一个块捕捉两个异常 try: x=input('Enter the first number: ') y=input('Enter the second number: ') print x/y except (ZeroDivisionError, TypeError, NameError): print 'Your numbers are bogus...' #8.6 捕捉对象 try: x=input('Enter the first number: ') y=input('Enter the second number: ') print x/y except (ZeroDivisionError, TypeError, NameError), e: print e #在Python 3.0 中, except子句会被写作 except (ZeroDivisionError, TypeError, NameError) as e #8.7 真正的全捕捉 try: x=input('Enter the first number: ') y=input('Enter the second number: ') print x/y except: print 'Something wrong happened...' >>> x=input('Enter the first number: ') Enter the first number: 10 >>> y=input('Enter the second number: ') Enter the second number: 0 >>> print x/y Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero #8.8 万事大吉 >>> try: ... print 'A simple task' ... except: ... print 'What? Something went wrong?' ... else: ... print 'Ah... It went as planned.' ... A simple task Ah... It went as planned. #只要有错误发生, 程序会不断要求重新输入 while True: try: x=input('Enter the first number: ') y=input('Enter the second number: ') value = x/y print 'x/y is', value except: print 'Invalid input. Please try again.' else: break #python ttb.py #Enter the first number: 1 #Enter the second number: 0 #Invalid input. Please try again. #Enter the first number: 'foo' #Enter the second number: 'bar' #Invalid input. Please try again. #Enter the first number: baz #Invalid input. Please try again. #Enter the first number: 10 #Enter the second number: 2 #x/y is 5 #打印更加有用的错误信息: while True: try: x=input('Enter the first number: ') y=input('Enter the second number: ') value = x/y print 'x/y is', value except Exception, e: print 'Invalid input:', e print 'Please try again' else: break #python ttc.py #Enter the first number: 1 #Enter the second number: 0 #Invalid input: integer division or modulo by zero #Please try again #Enter the first number: 'x' #Enter the second number: 'y' #Invalid input: unsupported operand type(s) for /: 'str' and 'str' #Please try again #Enter the first number: quuux #Invalid input: name 'quuux' is not defined #Please try again #Enter the first number: 10 #Enter the second number: 2 #x/y is 5 #8.8 最后 >>> x=None >>> try: ... x = 1/0 ... finally: ... print 'Cleaning up...' ... del x ... Cleaning up... Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: integer division or modulo by zero >>> >>> try: ... 1/0 ... except NameError: ... print 'Unknown variable' ... else: ... print 'That went well!' ... finally: ... print 'Cleaning up.' ... Cleaning up. Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: integer division or modulo by zero #异常和函数 >>> def faulty(): ... raise Exception('Someting is wrong') ... >>> def ignore_exception(): ... faulty() ... >>> def handle_exception(): ... try: ... faulty() ... except: ... print 'Exception handled' ... >>> >>> ignore_exception() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in ignore_exception File "<stdin>", line 2, in faulty Exception: Something is wrong >>> >>> handle_exception() Exception handled >>> #8.11 异常之禅 >>> def describePerson(person): ... print 'Description of', person['name'] ... print 'Age:', person['age'] ... if 'occupation' in person: ... print 'Occupation:', person['occupation'] ... def describePerson(person): print 'Description of', person['name'] print 'Age:', person['age'] try: print 'Occupation: ' + person['occupation'] except KeyError: pass person = {'name':'Jonathan', 'age':33} describePerson(person) #python ttd.py #Description of Jonathan #Age: 33 person = {'name':'Jonathan', 'age':33, 'occupation':'IBIT Support'} describePerson(person) #python ttd.py #Description of Jonathan #Age: 33 #Occupation: IBIT Support #8.12 小结 # 异常对象 # 引发异常 # 自定义异常类 # 捕捉异常: 使用try语句的except子句捕捉异常. 如果在except子句中不特别指定异常类, 那么所有的异常都会被捕捉. # 异常可以放在 元组 中以实现多个异常的指定. # 如果给except提供两个参数, 第二个参数就会绑定到 异常对象 上 # 在一个try语句中,可以包含多个except子句, 用来分别处理不同的异常 #else子句 如果主块try中没有发生异常, else子句就会被执行 #finally子句-- 如果需要确保某些代码不管是否有异常引发都要执行(比如清理代码, 关闭文件, 关闭网络套接字, 关闭数据库连接), # 那么这些代码可以放置在finally子句中 #异常和函数 在函数内引发异常时, 它就会被传播到函数调用的地方(对于方法也是一样) #8.12.1 新函数 # warnings.filterwarning(action....) 用于过滤警告 #Exception 所有异常的基类 #AttributeError 特性引用或赋值失败时引发 #IOError 试图打开不存在的文件(包括其他情况)时引发 #IndexError 在使用序列中不存在的索引时引发 #KeyError 在使用映射中不存在的键时引发 #NameError 在找不到名字(变量)时引发 #SyntaxError 在代码为错误形式时引发 #TypeError 在内建操作或函数应用于错误类型的对象时引发 #ValueError 在内建操作或函数应用于正确类型的对象,但该对象使用不合适的值时引发 #ZeroDivisionError 在除法或模除操作的第二个参数为0时引发