>

Python_异常处理详解,Python_Exception异常处理

- 编辑:正版管家婆马报彩图 -

Python_异常处理详解,Python_Exception异常处理

Python_Exception十分管理,python十分管理

关于异常处理:

Python中类定义可以作为对象传递,例子中类B继承了Exception类,在循环中每次raise一个异常类对象B,Except抓到这个异常,循环了3次,所以输出了B B B。

例子:
class B(Exception):
    pass

class C(B):
    pass

class D(C):
    pass

for cls in [B, C, D]:
    try:
        raise cls()
    except B:
        print("B")
    except C:
        print("C")
    except D:
        print("D")

执行结果:
B
B
B

关于丰富管理: Python中类定义可以当作对象传递,例子中类B传承了Exception类,在循环中年古稀之年是raise二个...

相当管理在任何一门编制程序语言里都是值得关切的一个话题,非凡的老大管理能够让你的次序特别健全,清晰的错误音信更能帮衬您飞速修复难点。在Python中,和不有的高端语言同样,使用了try/except/finally语句块来拍卖非常,假若你有另外编制程序语言的阅历,实施起来并简单。
非凡管理语句

try
    do something
excpet:
    do something
finally:
    do something

实例代码:

defdiv(a, b):
    try:
        print(a / b)
    except  ZeroDivisionError:
        print("Error: b should not be 0 !!")
    exceptExceptionase:
        print("Unexpected Error: {}".format(e))
    else:
        print('Run into else only when everything goes well')
    finally:
        print('Always run into finally block.')
# tests
div(2,0)
div(2,'bad type')
div(1,2)

# Mutiple exception in one line
try:
    print(a / b)
except(ZeroDivisionError, TypeError)as e:
    print(e)

# Except block is optional when there is finally
try:
  open(database)
finally:
  close(database)

# catch all errors and log it
try:
  do_work()
except:
  # get detail from logging module
  logging.exception('Exception caught!')
  # get detail from sys.exc_info() method
  error_type, error_value, trace_back = sys.exc_info()
  print(error_value)
  raise

总结:

  • except语句不是必需的,finally语句亦不是必得的,不过双方一定要有叁个,不然就从未try的意义了。
  • except语句能够有多个,Python会按except语句的一一依次相配你钦赐的非常,若是那么些已经管理就不会再进来前边的except语句。
  • except语句能够以元组情势同时内定多少个极其,参见实例代码。
  • except语句前边倘使不钦点特别类型,则暗中同意捕获全体非常,你能够通过logging恐怕sys模块获取当前非凡。
  • 假设要捕获非常后要重新抛出,请使用raise,前面不要带任何参数或新闻。
  • 不提出捕获并抛出同三个特别,借使是这么请考虑重构你的代码。
  • 不建议在不清楚逻辑的动静下捕获全体特别,有比较大可能率你隐敝了很严重的主题材料。
  • 尽量选择内置的极其管理语句来 替换try/except语句,譬如with语句,getattr()方法。
  • 抛出极其 raise 借使您供给自己作主抛出十三分贰个可怜,能够使用raise关键字,等同于C#和Java中的throw语句,其语法则则如 : raiseNameError("bad name!") raise关键字背后供给钦赐你抛出的特别类型,一般的话抛出的极度越详细越好,Python在exceptions模块内建了大多的极度类型,通过接纳dir()函数来查看exceptions中的至极类型,如下:
import exceptions
# ['ArithmeticError', 'AssertionError'.....]
print dir(exceptions)

本来你也能够查看Python的文书档案库举行更详尽的询问。
https://docs.python.org/2.7/library/exceptions.html#bltin-exceptions
自定义相当类型
Python中也足以自定义自身的非正规类型的不得了,只必要要从Exception类承继(直接或直接)即可:
class SomeCustomException(Exception):
pass

  • 诚如你在自定义至极类型时,必要思量的标题应当是以此可怜所选拔的场景。若是放置万分已经席卷了你供给的那三个,提议考虑采用内置 的那多少个类型。比如你希望在函数参数错误时抛出一个非凡,你只怕并无需定义三个InvalidArgumentError,使用内置的ValueError就能够。

经历案例
传递相当 re-raise Exception
捕捉到了非凡,但是又想再一次引发它(传递分外),使用不带参数的raise语句就可以:

def f1():
    print(1/0)
deff2():
  try:
    f1()
  except Exception as e:
    raise # don't raise e !!!
f2()

在Python第22中学,为了保险至极的总体音信,那么你捕获后再行抛出时相对无法在raise前边加上特别对象,否则你的trace新闻就能够从此处截断。以上是最简便易行的再度抛出拾贰分的做法。

还应该有部分本事可以考虑,比如抛出十一分前对十分的新闻进行立异。

def f2():
  try:
    f1()
  except Exception as e:
    e.args += ('more info',)
    raise

若果您有意思味明白愈来愈多,建议阅读这篇博客。
http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html
Python3对再一次传递格外有所立异,你能够本人尝尝一下,然而建议如故同上。

Exception 和 BaseException

当我们要捕获一个通用分外时,应该用Exception依旧BaseException?笔者建议您照旧看一下 官方文书档案表明,那多少个极其到底有甚分化吧? 请看它们中间的后续关系。

BaseException

+-- SystemExit

+-- KeyboardInterrupt

+-- GeneratorExit

+-- Exception

     +-- StopIteration...

     +-- StandardError...

     +-- Warning...

从Exception的层级结构来看,BaseException是最基础的不得了类,Exception承接了它。BaseException除了含有全数的Exception外还富含了SystemExit,KeyboardInterrupt和GeneratorExit八个可怜。

有此看来你的主次在抓获全部非常时更应该使用Exception并非BaseException,因为别的四个特别属于更加高等其余充裕,合理的做法应该是交给Python的解释器管理。
except Exception as e和 except Exception, e

代码示举个例子下:

try:
  do_something()
except NameError as e:# should
  pass
except KeyError, e:# should not
  pass

在Python2的不平日,你能够行使上述二种写法中的放肆一种。在Python3中您不得不使用第一种写法,第两种写法被屏弃掉了。第二个种写法可读性越来越好,况兼为了程序的包容性和末代移植的财力,请你也吐弃第两种写法。

raise "Exception string"

把字符串当成非常抛出看上去是一个不行简洁的点子,但事实上是三个可怜不好的习贯。

if is_work_done():
  pass
else:
  raise"Work is not done!"# not cool

下面的言辞假诺抛出拾叁分,那么会是这样的:

Traceback (most recent call last):
File"/demo/exception_hanlding.py", line48,in
raise"Work is not done!"
TypeError: exceptions must be old-style classesorderivedfromBaseException,notstr

那在Python2.4原先是勉强可以的做法,可是从未点名极度类型有望会让下游不可能准确捕获并拍卖那些极其,从而致使您的次第挂掉。轻巧说,这种写法是是封建时期的旧习,应该扔了。

采取内置的语法范式替代try/except

Python 本人提供了过多的语法范式简化了拾贰分的拍卖,比如for语句就管理的StopIteration相当,让您很流畅地写出二个巡回。
with语句在开采文件后会自动调用finally中的关闭文件操作。大家在写Python代码时应当尽量制止在碰着这种状态时还选取try/except/finally的挂念来管理。

# should not

try:
  f = open(a_file)
  do_something(f)
finally:
  f.close()

# should
with open(a_file) as f:
  do_something(f)

再比如,当我们必要拜候三个不分明的习性时,有望你会写出这么的代码:

try:
  test  = Test()
  name = test.name# not sure if we can get its name
except AttributeError:
  name ='default'

实际您能够选取更简短的getattr()来达到你的指标。

name = getattr(test,'name','default')

最好推行

  • 一级推行不压制编制程序语言,只是有个别条条框框和填坑后的获得。
  • 只管理你精晓的极度,幸免捕获全体 非凡然后吞掉它们。
  • 抛出的极度应该辨证开始和结果,有时候你明白这么些类型也猜不出所以然的。
  • 防止在catch语句块中干一些没意义的业务。
  • 毫无选取特别来决定流程,那样你的主次会Infiniti难懂和难保证。
  • 假若有供给,切记使用finally来刑满释放解除劳教能源。
  • 如若有亟待,请不要忘记在拍卖极度后做清理专门的工作依然回滚操作。

@ 晴天-平常搬砖,以为很好就搬过来。

本文由编程应用发布,转载请注明来源:Python_异常处理详解,Python_Exception异常处理