python中的raise语句,python中raise什么意思

  python中的raise语句,python中raise什么意思

  当程序出现错误时,系统会自动抛出异常。此外,Python还允许程序自己抛出异常,这可以通过引发语句来实现。

  在许多情况下,系统是否抛出异常可能需要根据应用程序的业务需求来决定。如果程序中的数据和执行与既定的业务需求不一致,这是一个例外。与业务需求不一致导致的异常必须由程序员决定,系统不能抛出这个异常。

  如果需要在程序中自己抛出异常,应该使用raise语句。Raise语句有以下三种常见用法:

  加注:一次加注。此语句引发在当前上下文中捕获的异常(如在except块中),或者默认情况下引发RuntimeError异常。

  引发异常类:引发后面跟一个异常类。该语句抛出指定异常类的默认实例。

  引发异常对象:引发指定的异常对象。

  以上三种用法都是针对引发一个异常实例(即使指定了异常类,实际上也是引发该类的默认实例),raise语句一次只能引发一个异常实例。

  raise语句可用于再次重写在以前的五子棋游戏中用于处理用户输入的代码:

  尝试:

  #使用逗号(,)作为分隔符,将用户输入的字符串分成两个字符串。

  x_str,y_str=inputStr.split(sep=,)

  #如果下棋的点不是空的

  if board[int(y _ str)-1][int(x _ str)-1]!= :

  #抛出默认的RuntimeError异常

  上升

  #将相应的列表元素分配给“”

  board[int(y _ str)-1][int(x _ str)-1]=""

  异常异常:

  打印(类型(e))

  InputStr=input(您输入的坐标不合法,请重新输入。象棋坐标应该是x,y格式\n )

  继续上面第7行的代码,程序使用raise语句来抛出一个异常。该程序认为,当用户试图在现有棋子的坐标点下棋时,它是一个例外。当Python解释器收到开发者自己抛出的异常时,也会停止当前的执行流程,跳转到异常对应的异常块,由异常块处理异常。也就是说,无论是系统自动引发的异常,还是程序员手动引发的异常,Python解释器在处理异常时都没有任何区别。

  即使是用户自己抛出的异常,也可以使用try except来捕捉。当然,您可以不去管它,让异常向上传播(首先是调用者)。如果异常到达Python解释器,程序将被中止。

  下面的示例演示了处理用户引发的异常的两种方法:

  defmain():

  尝试:

  #使用try.除了捕捉异常

  #此时,即使程序出现异常,也不会传播到主函数。

  mtd(3)

  异常异常:

  打印(“程序中出现异常3360”,e)

  #不要使用try.除了捕捉异常,异常会传播并导致程序停止。

  mtd(3)

  defnb

  sp;mtd(a):

  ifa>0:

  raiseValueError("a的值大于0,不符合要求")

  main()从上面程序可以看到,程序既可在调用 mtd(3) 时使用 try except 来捕获异常,这样该异常将会被 except 块捕获,不会传播给调用它的函数;也可直接调用 mtd(3),这样该函数的异常就会直接传播给它的调用函数,如果该函数也不处理该异常,就会导致程序中止。

  运行上面程序,可以看到如下输出结果:

  

程序出现异常:a的值大于0,不符合要求

  Traceback(mostrecentcalllast):

  File"C:\Users\mengma\Desktop\1.py",line13,in<module>

  main()

  File"C:\Users\mengma\Desktop\1.py",line9,inmain

  mtd(3)

  File"C:\Users\mengma\Desktop\1.py",line12,inmtd

  raiseValueError("a的值大于0,不符合要求")

  ValueError:a的值大于0,不符合要求

上面第一行输出是第一次调用 mtd (3) 的结果,该方法引发的异常被 except 块捕获并处理。后面的大段输出则是第二次调用 mtd(3) 的结果,由于该异常没有被 except 块捕获,因此该异常一直向上传播,直到传给 Python 解释器导致程序中止。

  第二次调用 mtd(3) 引发的以“File”开头的三行输出,其实显示的就是异常的传播轨迹信息。也就是说,如果程序不对异常进行处理,Python 默认会在控制台输出异常的传播轨迹信息。

  自定义异常类

  很多时候,程序可选择引发自定义异常,因为异常的类名通常也包含了该异常的有用信息。所以在引发异常时,应该选择合适的异常类,从而可以明确地描述该异常情况。在这种情形下,应用程序常常需要引发自定义异常。

  用户自定义异常都应该继承 Exception 基类或 Exception 的子类,在自定义异常类时基本不需要书写更多的代码,只要指定自定义异常类的父类即可。

  下面程序创建了一个自定义异常类(程序一):

  

classAuctionException(Exception):pass
上面程序创建了 AuctionException 异常类,该异常类不需要类体定义,因此使用 pass 语句作为占位符即可。

  在大部分情况下,创建自定义异常类都可采用与程序一相似的代码来完成,只需改变 AuctionException 异常的类名即可,让该异常的类名可以准确地描述该异常。

  except 和 raise 同时使用

  在实际应用中对异常可能需要更复杂的处理方式。当一个异常出现时,单靠某个方法无法完全处理该异常,必须由几个方法协作才可完全处理该异常。也就是说,在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要在该方法的调用者中才能完成,所以应该再次引发异常,让该方法的调用者也能捕获到异常。

  为了实现这种通过多个方法协作处理同一个异常的情形,可以在 except 块中结合 raise 语句来完成。如下程序示范了except 和 raise 同时使用的方法:

  

classAuctionException(Exception):pass

  classAuctionTest:

  def__init__(self,init_price):

  self.init_price=init_price

  defbid(self,bid_price):

  d=0.0

  try:

  d=float(bid_price)

  exceptExceptionase:

  #此处只是简单地打印异常信息

  print("转换出异常:",e)

  #再次引发自定义异常

  raiseAuctionException("竞拍价必须是数值,不能包含其他字符!")#①

  raiseAuctionException(e)

  ifself.init_price>d:

  raiseAuctionException("竞拍价比起拍价低,不允许竞拍!")

  initPrice=d

  defmain():

  at=AuctionTest(20.4)

  try:

  at.bid("df")

  exceptAuctionExceptionasae:

  #再次捕获到bid()方法中的异常,并对该异常进行处理

  print('main函数捕捉的异常:',ae)

  main()

上面程序中 9~13 行代码对应的 except 块捕获到异常后,系统打印了该异常的字符串信息,接着引发一个 AuctionException 异常,通知该方法的调用者再次处理该 AuctionException 异常。所以程序中的 main() 函数,也就是 bid() 方法的调用者还可以再次捕获 AuctionException 异常,井将该异常的详细描述信息打印出来。

  这种 except 和 raise 结合使用的情况在实际应用中非常常用。实际应用对异常的处理通常分成两个部分:

  应用后台需要通过日志来记录异常发生的详细情况;

  应用还需要根据异常向应用使用者传达某种提示;

  在这种情形下,所有异常都需要两个方法共同完成,也就必须将 except 和 raise 结合使用。

  如果程序需要将原始异常的详细信息直接传播出去,Python 也允许用自定义异常对原始异常进行包装,只要将上面 ① 号代码改为如下形式即可:

  

raiseAuctionException(e)
raise 不需要参数

  正如前面所看到的,在使用 raise 语句时可以不带参数,此时 raise 语句处于 except 块中,它将会自动引发当前上下文激活的异常;否则,通常默认引发 RuntimeError 异常。

  例如,将上面程序改为如下形式:

  

classAuctionException(Exception):pass

  classAuctionTest:

  def__init__(self,init_price):

  self.init_price=init_price

  defbid(self,bid_price):

  d=0.0

  try:

  d=float(bid_price)

  exceptExceptionase:

  #此处只是简单地打印异常信息

  print("转换出异常:",e)

  #再次引发自定义异常

  raise

  ifself.init_price>d:

  raiseAuctionException("竞拍价比起拍价低,不允许竞拍!")

  initPrice=d

  defmain():

  at=AuctionTest(20.4)

  try:

  at.bid("df")

  exceptAuctionExceptionasae:

  #再次捕获到bid()方法中的异常,并对该异常进行处理

  print('main函数捕捉的异常:',ae)

  main()

正如从 13 行代码所看到的,此时程序在 except 块中只是简单地使用 raise 语句来引发异常,那么该 raise 语句将会再次引发该 except 块所捕获的异常。运行该程序,可以看到如下输出结果:

  

转换出异常:couldnotconvertstringtofloat:'df'

  main函数捕获的异常:<class'ValueError'>

从输出结果来看,此时 main() 函数再次捕获了 ValueError,它就是在 bid() 方法中 except 块所捕获的原始异常。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: