diff --git "a/\347\274\226\347\240\201\350\247\204\350\214\203/openKylin-python\350\257\255\350\250\200\351\200\232\347\224\250\347\274\226\347\250\213\350\247\204\350\214\203.md" "b/\347\274\226\347\240\201\350\247\204\350\214\203/openKylin-python\350\257\255\350\250\200\351\200\232\347\224\250\347\274\226\347\250\213\350\247\204\350\214\203.md" index bd285f5fa1e6f52c021bf8db15e28d1c4679a932..798c6fc30acc4769aab14a9f8f324abf3d561e27 100644 --- "a/\347\274\226\347\240\201\350\247\204\350\214\203/openKylin-python\350\257\255\350\250\200\351\200\232\347\224\250\347\274\226\347\250\213\350\247\204\350\214\203.md" +++ "b/\347\274\226\347\240\201\350\247\204\350\214\203/openKylin-python\350\257\255\350\250\200\351\200\232\347\224\250\347\274\226\347\250\213\350\247\204\350\214\203.md" @@ -90,7 +90,7 @@ yield和return语句只有在函数的上下文中才有意义。在函数外使 # 2 错误和异常 -## 规则2.1 异常应该从Exception类派生(python:S5632) +## 规则2.1 引发的异常类应该派生自BaseException类(python:S5632) 在Python3中,试图引发一个不是从BaseException派生的对象将引发一个TypeError异常。在Python2中可以这样编程,但为了与Python3兼容,不应该再这样做。当需要自定义异常类时,应该继承自Exception,而不是BaseException。 @@ -115,7 +115,41 @@ yield和return语句只有在函数的上下文中才有意义。在函数外使 ### 参考资料 [python手册-错误与异常](https://docs.python.org/zh-cn/3/tutorial/errors.html) -## 规则2.2 Break、continue和return语句不应出现在“finally”分支中(python:S1143) + +## 规则2.2 捕获的异常类应该派生自BaseException类(python:S5708) +在Python 3中,试图在exception语句中捕获不是从BaseException派生的对象将引发TypeError异常。在Python 2中,可以提出旧样式的类,但为了与Python 3兼容,不应该再这样做了。为了在exception语句中捕获多个异常,应该提供一个异常类元组。如果要创建自定义Exception类,请注意,自定义异常应继承自Exception,而不是BaseException。Exception允许捕获所有异常,除了哪些明确要求解释器停止的异常之外。例如Exception不能捕获KeyboardInterrupt和GeneratorExit,这不是一个错误。 + +### 错误代码 + + class CustomException: + """An Invalid exception class.""" + + try: + "a string" * 42 + except CustomException: # Noncompliant + print("exception") + except (None, list()): # Noncompliant * 2 + print("exception") + + try: + "a string" * 42 + except [TypeError, ValueError]: # Noncompliant. Lists are not accepted. + print("exception") + except {TypeError, ValueError}: # Noncompliant. Sets are not accepted. + print("exception") + +### 正确代码 + class MyError(Exception): + pass + + try: + "a string" * 42 + except (MyError, TypeError): + print("exception") +### 参考资料 +[pep-0352](https://peps.python.org/pep-0352/#exception-hierarchy-changes) + +## 规则2.3 Break、continue和return语句不应出现在“finally”分支中(python:S1143) 在finally分支中使用return、break或continue将阻止在try、else或except块中引发的未处理异常的传递,并且将忽略它们的返回语句。一些重要的异常不应该被忽略:例如当程序调用sys.exit()时引发的SystemExit异常,又如当用户按下中断键要求程序停止时引发的KeyboardInterrupt异常,这两个异常通常应该一直传递到应用程序停止。当需要清理时,可以捕获它们,但应该立即将它们再次引发。 ### 错误代码 @@ -205,7 +239,7 @@ yield和return语句只有在函数的上下文中才有意义。在函数外使 except Exception: logging.exception("Failed") # Ignore all "Exception" subclasses yet allow SystemExit and other important exceptions to pass -## 规则2.3 所有的except异常处理都应该能够捕获异常(python:S1045) +## 规则2.4 所有的except异常处理都应该能够捕获异常(python:S1045) 异常处理程序(except块)按照它们编写的顺序进行评估。一旦找到匹配项,评估过程停止。 在某些情况下,后面的异常处理程序是无效代码,因为它永远无法捕获任务异常: 1、一个基类异常处理程序后面跟着一个派生自该基类的类的异常处理程序,那么第二个异常处理程序将永远不会被触发。 @@ -257,7 +291,7 @@ yield和return语句只有在函数的上下文中才有意义。在函数外使 except BaseException as e: print(e) -## 规则2.4 except语句中不应该使用异常类的布尔表达式(python:S5714) +## 规则2.5 except语句中不应该使用异常类的布尔表达式(python:S5714) except语句的表达式只能是派生自BaseException的类,或者由这些类组成的元组(在python 2中还可以是旧式类,在python 3中已被删除) 当在except语句的表达式中使用了异常类的布尔表达式时,就会引发问题。这样的表达式的结果是当个异常类,但这不是开发人员的本意。 ### 错误代码