Python 面向对象(其四)
python中异常简述
超人小明经历了太多生死,开始有点魔化了
---------------------------------------魔化超人小明--------------------属性------------------------------------方法----------------间歇性入魔:每隔一段时间,就会入魔一下突发性入魔:每次一入魔,小明都会干出很多奇怪而凶残的事情心魔洗练:小明在不停的自我压制魔念
方法说明:
- 间歇性入魔:
- 因为都好多次了,所以小明甚至制定除了如何应对这种入魔的策略,可以不影响其他人事的情况下唤回自己
- 对于异常情况可以额外预防,甚至可以优雅回退
- 突发性入魔:
- 因为不可预料性,所以一旦出现这种状况,只能让周围的人回避,并请出阿花阿芳阿草来进行唤回
- 异常情况
- 心魔洗练:
- 小明一直在自我调节,压制魔念,让自己更清明
- 代码中的容错,一旦写的不好就完犊子了
如上,代码表现为:
1 #! coding:utf-8 2 import random 3 4 #自定义异常表现 5 class BlackInsideError(Exception): 6 ''' 7 通常仅需要重写这两个方法就好 8 ''' 9 10 def __init__(self, value): 11 ''' 12 可以在异常类中进行各种预设的处理情况 13 ''' 14 self.value = value 15 BlackSuperManXiaoMing.isNormal = False 16 17 def __str__(self): 18 ''' 19 print Exception时使用。所有支持print(obj)的对象都有__str__方法 20 ''' 21 return "{},每次入魔小明都会干出奇怪而可怕的事情".format(self.value) 22 23 24 class BlackSuperManXiaoMing(SuperXiaoMing): 25 26 isNormal = True 27 28 def __init__(self,relationship): 29 super(BlackSuperManXiaoMing, self).__init__(relationship) 30 31 def call_me_back(self): 32 BlackSuperManXiaoMing.isNormal = True 33 return "小明入魔了,需要年轻貌美的女士来亲一口才可以恢复" 34 35 def rolate_black(self): 36 BlackSuperManXiaoMing.isNormal = False 37 return "小明入魔了,快点唤醒他吧。 咒语是:xiaoming.call_me_back" 38 39 def is_black(self): 40 if BlackSuperManXiaoMing.isNormal: 41 return "小明现在很正常" 42 else: 43 return "小明入魔了" 44 45 def suddenly_black(self): 46 return BlackInsideError("突然入魔") 47 48 def black_to_white(self): 49 print("小明发功中....") 50 if random.randint(1,100000000)%4 < 2 : 51 return "小明成功的压制了魔念" 52 else: 53 raise BlackInsideError("小明没有压制成功") 54 55 if __name__ == '__main__': 56 57 black = BlackSuperManXiaoMing("阿花") 58 print(black.is_black()) 59 print(black.rolate_black()) 60 print(black.is_black()) 61 print(black.call_me_back()) 62 print(black.is_black()) 63 # ------------------------output-------------- 64 # 小明现在很正常 65 # 小明入魔了,快点唤醒他吧。 咒语是:xiaoming.call_me_back 66 # 小明入魔了 67 # 小明入魔了,需要年轻貌美的女士来亲一口才可以恢复 68 # 小明现在很正常 69 70 b = black.suddenly_black() 71 if isinstance(b, BlackInsideError): 72 print ("小明异常了") 73 print (b) 74 else: 75 print ("呵呵哒") 76 # ------------------------output-------------- 77 # 小明异常了 78 # 突然入魔,每次入魔小明都会干出奇怪而可怕的事情 79 80 for i in range(10): 81 b = black.black_to_white() 82 if isinstance(b, BlackInsideError): 83 print (b) 84 else: 85 print ("Oh yeah! {}".format(b)) 86 # ------------------------output-------------- 87 # 小明发功中.... 88 #小明成功的压制了魔念 89 # 小明发功中.... 90 # Traceback (most recent call last): 91 # File "C:/Users/thinkpad/PycharmProjects/test_proto/test_xiaoming/SuperXiaoMing.py", line 62, in92 # b = black.black_to_white() 93 # File "C:/Users/thinkpad/PycharmProjects/test_proto/test_xiaoming/SuperXiaoMing.py", line 43, in black_to_white 94 # raise BlackInsideError("小明没有压制成功") 95 # __main__.BlackInsideError: 小明没有压制成功,每次入魔小明都会干出奇怪而可怕的事情 96 97 try: 98 for i in range(10): 99 100 b = black.black_to_white() 101 if isinstance(b, BlackInsideError): 102 print (b) 103 else: 104 print ("Oh yeah! {}".format(b)) 105 except: 106 # 兼容错误,并忽略 107 print ("小明入魔了,完犊子了") 108 # pass指的是后续该代码块后续的部分,这里无实际意义 109 pass 110 else: 111 print ("小明已经累计10次压制成功了") 112 finally: 113 print ("本次压制结束") 114 # ------------------------output-------------- 115 #小明发功中.... 116 # Oh yeah! 小明成功的压制了魔念 117 # 小明发功中.... 118 # Oh yeah! 小明成功的压制了魔念 119 # 小明发功中.... 120 # Oh yeah! 小明成功的压制了魔念 121 # 小明发功中.... 122 # Oh yeah! 小明成功的压制了魔念 123 # 小明发功中.... 124 # Oh yeah! 小明成功的压制了魔念 125 # 小明发功中.... 126 # Oh yeah! 小明成功的压制了魔念 127 # 小明发功中.... 128 # Oh yeah! 小明成功的压制了魔念 129 # 小明发功中.... 130 # Oh yeah! 小明成功的压制了魔念 131 # 小明发功中.... 132 # 小明入魔了,完犊子了 133 # 本次压制结束
python异常综述:
python中异常大致可以分为3类:
- 系统级别的异常
- 强制结束进程
- SystemExit
- 键盘Ctrl-C 退出
- KeyboardInterrupt
- 对象异常销毁
- GeneratorExit
- 强制结束进程
- 可忽略的异常
- 各种Warning,比如定义一些不用的变量之类,多见于IDE,直接脚本run不常见。可忽略
- 代码级崩溃异常
- 各种Error
- 各种Error
各Exception的调用关系如下:
BaseException+-- SystemExit+-- KeyboardInterrupt+-- GeneratorExit+-- Exception+-- StopIteration+-- StandardError| +-- BufferError| +-- ArithmeticError| | +-- FloatingPointError| | +-- OverflowError| | +-- ZeroDivisionError| +-- AssertionError| +-- AttributeError| +-- EnvironmentError| | +-- IOError| | +-- OSError| | +-- WindowsError (Windows)| | +-- VMSError (VMS)| +-- EOFError| +-- ImportError| +-- LookupError| | +-- IndexError| | +-- KeyError| +-- MemoryError| +-- NameError| | +-- UnboundLocalError| +-- ReferenceError| +-- RuntimeError| | +-- NotImplementedError| +-- SyntaxError| | +-- IndentationError| | +-- TabError| +-- SystemError| +-- TypeError| +-- ValueError| +-- UnicodeError| +-- UnicodeDecodeError| +-- UnicodeEncodeError| +-- UnicodeTranslateError+-- Warning+-- DeprecationWarning+-- PendingDeprecationWarning+-- RuntimeWarning+-- SyntaxWarning+-- UserWarning+-- FutureWarning+-- ImportWarning+-- UnicodeWarning+-- BytesWarning
异常捕获与优雅滚回
-
通用兼容
- 如果是以Exception对象返回,就
- 使用if obj: …
- 使用 isinstance(obj, Exception)
- 如果是raise Exception,或者 代码Exception直接出来
- 使用try…except…else…finally
- 如果是以Exception对象返回,就
-
可回滚式兼容
- with xxx as obj:
- 优雅而从容,装逼利器
with操作(文件操作为例)
简单写法1.0
f = open("openedfile","r") content = f.read() f.close()
这种写法不存在任何健壮性,代码中存在的可能异常的地方有:
- 文件件不存在
- 没有读取权限
- 读取过程中被篡改内容
- 文件对象句柄忘记关闭等
改进写法1.1
解决问题1,2,4
try:f = open("openedfile","r") except Exception as e:print ("file opened fail! ")print (e) else:content = f.read()f.close()
改进写法1.2
解决问题1,2,3,4
try:f = open("openedfile","r")content = f.read() except Exception as e:print ("file opened fail! ")print (e) else:f.close()
改进写法2.0
with open("openedfile") as f:content = f.close()
说明:
- with是一种原子性操作,with里面的内容在失败后可以自动进行回滚,目前file、db等大多数欧快都自动支持with回滚
- with可以和yeild进行对照理解
with 工作原理简单解释
with 语句会先调用 with obj 中obj.enter()方法进行初始化操作,然后开始执行with中的代码块。
如果执行完成/失败,会调用obj中的obj.exit()方法进行退出
So,我们也可以自己定义一些可被with的类给使用者友好调用。
#! coding:utf-8 class XiaoMing(object):angry = 0def __enter__(self):'''返回对向自己:return:'''print ("我是小明,地球的保护神")return selfdef __exit__(self, exc_type, exc_val, exc_tb):'''场景恢复,回滚等操作:param exc_type: 过程中的异常class:param exc_val: 异常类中的value,即说明:param exc_tb: 异常中的堆栈信息,即通常看到的trace back d对象:return: 返回True表示已经自己回滚完成,不需要外部额外处理;返回False表示需要外部捕获Exception'''XiaoMing.angry = 0print ("执行结束,请退出")print ("exc_type : {}, exc_val : {}, exc_tb : {}".format(exc_type, exc_val, exc_tb))print (dir(exc_tb))return Truedef excep(self):XiaoMing.angry = 999999a = 1/0xiaoming = XiaoMing() # print (dir(xiaoming)) with xiaoming:print ("小明很牛逼啊")xiaoming.excep()print ("after with, I'm here")#--------------output------------------- # 我是小明,地球的保护神 # 小明很牛逼啊 # 执行结束,请退出 # exc_type :, exc_val : division by zero, exc_tb : # ['tb_frame', 'tb_lasti', 'tb_lineno', 'tb_next'] # after with, I'm here
引申阅读:
- contextlib 参考链接
- nested 参考链接
转载于:https://www.cnblogs.com/SilenceCity/p/pythonOO4.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
