小明和阿芳,python 面向对象:类的异常表现

2023年 7月 12日 36.9k 0

类的异常表现

  • 小明被绿了,开始暴躁了。
    ---------------------------------------
                      超人小明
    --------------------属性----------------
    --------------------方法----------------
    滚出去: 多次让小明滚出去,可能会挨揍
    写给老婆阿芳的家信:每次想起深爱的阿花,小明都会崩溃
  • 方法说明:
    • 滚出去:每次让小明滚出去都可能收获一个意料之外的拳头
    • 写给老婆阿芳的家信:每次调用时,小明都会自己崩溃

如上,用代码表现出来就是

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 
#     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 
#     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 "其实,小明有个美满的家庭了现在,日子很幸福"

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论