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, in <module>
 92 #     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

 

各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
  • 可回滚式兼容

    • 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 = 0
    def __enter__(self):
        '''
            返回对向自己
        :return:
        '''
        print ("我是小明,地球的保护神")
        return self

    def __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 = 0
        print ("执行结束,请退出")
        print ("exc_type : {}, exc_val : {}, exc_tb : {}".format(exc_type, exc_val, exc_tb))
        print (dir(exc_tb))
        return True

    def excep(self):
        XiaoMing.angry = 999999
        a = 1/0

xiaoming =  XiaoMing()
# print (dir(xiaoming))
with xiaoming:
    print ("小明很牛逼啊")
    xiaoming.excep()

print ("after with, I'm here")

#--------------output-------------------
# 我是小明,地球的保护神
# 小明很牛逼啊
# 执行结束,请退出
# exc_type : <class 'ZeroDivisionError'>, exc_val : division by zero, exc_tb : <traceback object at 0x06358940>
# ['tb_frame', 'tb_lasti', 'tb_lineno', 'tb_next']
# after with, I'm here

引申阅读:

 

转载于:https://www.cnblogs.com/SilenceCity/p/pythonOO4.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值