小明和阿芳,python 面向对象:类的异常表现
类的异常表现
- 小明被绿了,开始暴躁了。
--------------------------------------- 超人小明 --------------------属性---------------- --------------------方法---------------- 滚出去: 多次让小明滚出去,可能会挨揍 写给老婆阿芳的家信:每次想起深爱的阿花,小明都会崩溃 - 方法说明:
- 滚出去:每次让小明滚出去都可能收获一个意料之外的拳头
- 写给老婆阿芳的家信:每次调用时,小明都会自己崩溃
如上,用代码表现出来就是
class SuperGreenManXiaoMing(SuperManXiaoMing):
def __init__(self, relationship):
super(SuperGreenManXiaoMing,self).__init__(relationship)
self.__goOut_times = 0
def goOut(self):
self.__goOut_times+= 1
if self.__goOut_times < 3:
return "心情不好,憋说话!%s"%self.relationship
else:
return Exception("感受我社会主义愤怒的绿色小拳拳吧")
def loveToWife(self):
wife = 0
love = 999.99
print "阿芳,额对你的爱有 %s 深"%(love/wife)
实际调用效果如下:
green = SuperGreenManXiaoMing("brother")
print green.goOut()
print green.goOut()
g = green.goOut()
print isinstance(g, Exception)
print g
# ------------output----------
# 心情不好,憋说话!brother
# 心情不好,憋说话!brother
# True
# 感受我社会主义愤怒的绿色小拳拳吧
green.loveToWife()
# ------------output----------
# Traceback (most recent call last):
# File "/Users/Silence/Documents/xiaoming.py", line 110, in <module>
# green.loveToWife()
# File "/Users/Silence/Documents/xiaoming.py", line 75, in loveToWife
# print "阿芳,额对你的爱有 %s 深"%(love/wife)
# ZeroDivisionError: float division by zero
可以看出:
- loveToWife()函数是class内部异常,只能捕获兼容,不能任何规避;
- goOut()由于是返回的一个Excetion对象,所以即可以在小于3次时规避,也后期进行兼容。
另外,goOut的异常返回还有一种书写方式,如下:
def goOut(self):
self.__goOut_times+= 1
if self.__goOut_times < 3:
return "心情不好,憋说话!%s"%self.relationship
else:
raise Exception("感受我社会主义愤怒的绿色小拳拳吧")
这种写法,会将Exception直接抛出给最上层调用方,执行效果如下
green = SuperGreenManXiaoMing("brother")
print green.goOut()
print green.goOut()
g = green.goOut()
# ------------output----------
# 心情不好,憋说话!brother
# 心情不好,憋说话!brother
# Traceback (most recent call last):
# File "/Users/Silence/Documents/xiaoming.py", line 108, in <module>
# g = green.goOut()
# File "/Users/Silence/Documents/xiaoming.py", line 71, in goOut
# raise Exception("感受我社会主义愤怒的绿色小拳拳吧")
# Exception: 感受我社会主义愤怒的绿色小拳拳吧
在上述三种异常的表现方式,区别在于:
| 异常表现 | 严重级别 | 友好度 | 使用场景 |
|---|---|---|---|
| return Exception() | 中 | 高 | 多参数返回时,作为协议中正确字段的返回 |
| raise Exception() | 高 | 中 | 对于正常业务流中的异常,不做完善兼容,完全寄希望于调用方来兼容 |
| 1/0(也可以称呼为code Exception) | 高 | 差 | 代码bug |
类的异常调用与兼容
- return Exception
- 接口协议中的一个正常字段,正常判断就可以
class SuperGreenOldManXiaoMing(SuperGreenManXiaoMing):
"""docstring for SuperGreenManXiaoMing"""
def __init__(self, relationship):
super(SuperGreenOldManXiaoMing, self).__init__(relationship)
def goOut(self):
if self.relationship in ["sister","brother","parent"]:
return "你们牛逼,听你的", None
elif self.relationship in ["wife", "girlfriend"]:
return "", Exception("憋跟我说话")
else:
return "滚粗", Exception("不想理你们")
old = SuperGreenOldManXiaoMing("sister")
out, e = old.goOut()
if not e:
print "小明没有揍我,哈哈哈"
else:
print "小明揍我了",e
- Raise Exception
- 直接抛出一个异常,如果调用方比较坑,不想兼容,则会出现互相坑的情况;
- 调用方通常会为了这个写一堆try…except…
class SuperGreenBoringManXiaoMing(SuperGreenManXiaoMing):
"""docstring for SuperGreenManXiaoMing"""
def __init__(self, relationship):
super(SuperGreenBoringManXiaoMing, self).__init__(relationship)
def goOut(self):
if self.relationship in ["sister","brother","parent"]:
return "你们牛逼,听你的"
else:
raise Exception("不想理你们")
boring = SuperGreenBoringManXiaoMing("boss")
try:
b = boring.goOut()
except:
print "我挡!小明想揍我,可惜没揍到"
pass
- code Exception
- 直接提bug修改吧
自定义异常
异常类和错误类,一句话概括为:包含错误文本信息的特殊class结构
目前python中所有的Error、Exception都继承自BaseException,而我们常用的Exception则指所有常见错误的基类,不包括语法错误等。
为什么要自定义异常?
- 虽然小明被绿了以后,除了兄弟姐妹父母外,别人的话都听不进去,但是,不同的人说话还是有区别的
- 交情好的人,小明可以选择耐着性子听听
- 交情一般的人,小明会给一些眼神和委婉的表达
- 没交情甚至落井下石的人,小明会直接上手揍了
对于听不进去的情形,我们都可以标记为Exception,但是不同的场景,Exception的处理是不一样的
代码解释为:
class RelationGoodError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
ming = SuperGreenManXiaoMing("friend")
ming.age = 42
return "道理我都懂,但是能不能过去还是得看自己啊"
class RelationNormalError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return "给你们一个让我安静的眼神,自己体会"
class RelationBadError(Exception):
def __init__(self, value):
self.value = value
def __str__(self)
return "来呀,感受下我心中的愤怒吧!"
class SuperGreenBoringManXiaoMing(SuperGreenManXiaoMing):
def __init__(self, relationship):
super(SuperGreenBoringManXiaoMing, self).__init__(relationship)
def goOut(self):
if self.relationship in ["sister","brother","parent"]:
raise RelationGoodError("你们牛逼,听你的")
elif self.relationship in ["friend", "classmates"]:
raise RelationNormalError("不想理你们")
else:
raise RelationBadError("接受社会主义绿色小拳头吧!")
boring = SuperGreenBoringManXiaoMing("boss")
try:
b = boring.goOut()
# except 可以多个,用于区分不同的Error
# 同一个except 里面,可以汇总多个Exception,都使用一种处理结果
except RelationGoodError, RelationNormalError:
print "我挡!小明想揍我,可惜没揍到"
except RelationBadError, e:
print "我擦,真揍我!"
print e
finally:
print "其实,小明有个美满的家庭了现在,日子很幸福"
THE END






