zoukankan      html  css  js  c++  java
  • 第14条:尽量用异常来表示特殊情况,而不要返回Nono

    核心知识点:

    1.用None这个返回值来表示特殊意义的函数,很容易使调用者犯错,因为None和0以及空字符串之类的值,在条件表达式里都会评估为False。

    2.两种方法:二元法;将异常抛给上一级直接报错。

    编写工具函数(utility function)时,我们有时候喜欢给None这个返回值赋予特殊意义,有时候这么做是合理地,有时候就会出错。

    例如要编写辅助函数,计算两数相除的商,在除数为0的情况下,计算结果是没有明确含义的,所以似乎应该返回None,就像下面这样:

    In [1]: def divide(a,b):
       ...:     try:
       ...:         return a / b
       ...:     except ZeroDivisionError:
       ...:         return None
       ...:     
    #貌似没有什么问题
    #执行几次试试
    In [2]: divide(1,2)
    Out[2]: 0.5
    
    In [3]: divide(1,0)
    
    In [4]: divide(0,1)
    Out[4]: 0.0

    貌似是没有什么问题,但是当在if语句中拿这个计算结果做判断时,会出现问题。

    我们可能不会专门去判断函数的返回值是否为None,而是:只要返回与False等效的运算结果,就说明函数出错了。

    这样明显有漏洞,当a=0,函数没有报错,但是按照上面的逻辑却是会报错。

    如果None这个返回值,对函数有特殊意义(在上面的例子中,None的特殊意义就是异常),那么在编写Python代码时,就很容易犯上面这种错误。

    有两种方法可以减少这种错误:

    第一种方法,是把返回值拆成两部分,并放到二元组(two-tuple)里面。二元组的首个元素表示操作是否成功,接下来的那个元素,才是真正的运算结果。

    In [9]: def divide(a,b):
       ...:     try:
       ...:         return True,a / b
       ...:     except ZeroDivisionError:
       ...:         return False, None
       ...:     
    
    In [10]: divide(1,0)
    Out[10]: (False, None)
    
    In [11]: divide(0,1)
    Out[11]: (True, 0.0)

    调用该函数的人需要解析这个元祖。这就使得不能只根据结果来遐想了,而必须根据运算状态的那个元素来做判断。

    第二种办法更好一些,那就是根本不返回None,而是把异常把异常抛给上一级,使得调用者必须应对它。

    In [13]: def divide(a,b):
        ...:     try:
        ...:         return a / b
        ...:     except ZeroDivisionError as e:
        ...:         raise ValueError('Invalid inputs') from e
        ...:     

    调用者需要处理因输入值无效而引发的异常。

    调用者无需用条件语句来判断函数的返回值,因为如果函数没有抛出异常,返回值自然就是正确的,这样写出来的异常处理代码,也比较清晰。

  • 相关阅读:
    2020Java面试题及答案,刷这些题,准没错!
    作为一个面试官,我想问问你Redis分布式锁怎么搞?
    你说研究过Spring里面的源码,循环依赖你会么?
    一口气说出 6种 延时队列的实现方案,面试稳稳的
    我可真是醉了,一个SpringBoot居然问了我30个问题
    最强Dubbo面试题,附带超级详细答案
    平安银行Java社招五面面经,目前最全面的,38个面试题以及答案
    Java电子书高清PDF集合免费下载
    Python处理json模块的详细介绍
    用Python写一个“离线语音提示器”来提醒我们别忘记了时间
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/7994368.html
Copyright © 2011-2022 走看看