溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

分析Python的錯(cuò)誤,調(diào)試和測(cè)試方法

發(fā)布時(shí)間:2021-11-03 17:53:34 來源:億速云 閱讀:157 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“分析Python的錯(cuò)誤,調(diào)試和測(cè)試方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“分析Python的錯(cuò)誤,調(diào)試和測(cè)試方法”吧!

  錯(cuò)誤處理

  在預(yù)防程序發(fā)生運(yùn)行錯(cuò)誤的時(shí)候,可以預(yù)先設(shè)置返回一個(gè)錯(cuò)誤代碼,然后在執(zhí)行程序的時(shí)候,就會(huì)知道程序是否正確。

  用錯(cuò)誤碼來表示是否出錯(cuò)有時(shí)候也十分的不方便,因?yàn)楹瘮?shù)本身應(yīng)該返回的正常結(jié)果和錯(cuò)誤碼混在一起,會(huì)導(dǎo)致必須用大量的代碼去判斷代碼是否出錯(cuò):

  def foo():

  r = some_function()

  if r == (-1):

  return -1

  return r

  def bar():

  r = foo()

  if r==(-1):

  print('Error')

  else:

  pass

  一旦發(fā)生錯(cuò)誤,還需要各個(gè)函數(shù)之間互相傳遞,用起來不方便,所以try…except…finally就被廣泛的用于試驗(yàn)錯(cuò)誤。

  try

  下面這個(gè)例子可以讓我們了解try的使用方法:

  >>> try:

  print("try...")

  r = 10 / 0

  print("result:",r)

  except ZeroDivisionError as e:

  print("except:",e)

  finally:

  print("Finally")

  try...

  except: division by zero

  Finally

  如果執(zhí)行出錯(cuò),則后續(xù)代碼不會(huì)繼續(xù)執(zhí)行,而是直接跳轉(zhuǎn)至錯(cuò)誤處理代碼,即except語句塊,執(zhí)行完except后,如果有finally語句塊,則執(zhí)行finally語句塊,至此,執(zhí)行完畢。

  如果將上面的0改成5,則不會(huì)報(bào)錯(cuò),正常運(yùn)行。

  >>> try:

  print("try...")

  r = 10 / 5

  print("result:",r)

  except ZeroDivisionError as e:

  print("except:",e)

  finally:

  print("Finally")

  try...

  result: 2.0

  Finally

  可以看出不再執(zhí)行except語句,只要一個(gè)程序中有finally語句,他肯定會(huì)被執(zhí)行。

  int()函數(shù)可能會(huì)拋出ValueError,所以我們用一個(gè)except捕獲ValueError,用另一個(gè)except捕獲ZeroDivisionError。此外,如果沒有錯(cuò)誤發(fā)生,可以在except語句塊后面加一個(gè)else,當(dāng)沒有錯(cuò)誤發(fā)生時(shí),會(huì)自動(dòng)執(zhí)行else語句:

  try:

  print('try...')

  r = 10 / int('5')

  print('result:', r)

  except ValueError as e:

  print('ValueError:', e)

  except ZeroDivisionError as e:

  print('ZeroDivisionError:', e)

  else:

  print('no error!')

  finally:

  print('finally...')

  print('END')

  Python的錯(cuò)誤其實(shí)也是一種類,所有的錯(cuò)誤類型都繼承自BaseException,所以在使用except不但捕獲該類型的錯(cuò)誤,還把其子類也“一網(wǎng)打盡”:

  try:

  foo()

  except ValueError as e:

  print('ValueError')

  except UnicodeError as e:

  print('UnicodeError')

  第二個(gè)except永遠(yuǎn)也捕獲不到UnicodeError,因?yàn)閁nicodeError是ValueError的子類,如果有,也被第一個(gè)except給捕獲了。

  常見錯(cuò)誤及其關(guān)系

  不需要在每個(gè)可能出錯(cuò)的地方去捕獲錯(cuò)誤,只要在合適的層次去捕獲錯(cuò)誤就可以了。

  def foo(s):

  return 10 / int(s)

  def bar(s):

  return foo(s) * 2

  def main():

  try:

  bar('0')

  except Exception as e:

  print('Error:', e)

  finally:

  print('finally...')

  調(diào)用棧

  如果錯(cuò)誤沒有被捕獲,它就會(huì)一直往上拋,最后被Python解釋器捕獲,打印一個(gè)錯(cuò)誤信息,然后程序退出。下面這個(gè)例子可以很好地展示這種操作:

  def foo(s):鄭州婦科醫(yī)院哪家好 http://www.120zzzy.com/

  return 10 / int(s)

  def bar(s):

  return foo(s) * 2

  def main():

  bar('0')

  main()

  運(yùn)行顯示結(jié)果:

  Traceback (most recent call last):

  File "F:/python文件/tiaoshi/__init__.py", line 10, in

  main()

  File "F:/python文件/tiaoshi/__init__.py", line 8, in main

  bar('0')

  File "F:/python文件/tiaoshi/__init__.py", line 5, in bar

  return foo(s) * 2

  File "F:/python文件/tiaoshi/__init__.py", line 2, in foo

  return 10 / int(s)

  ZeroDivisionError: division by zero

  下面我們就來解讀一下這個(gè)輸出的結(jié)果,首先第一句:

  Traceback (most recent call last):

  告訴我們這是錯(cuò)誤的跟蹤信息。

  File “F:/python文件/tiaoshi/init.py”, line 10, in <\module>

  main()

  代碼中第10行調(diào)用main函數(shù)出錯(cuò),原因是第8行.

  File “F:/python文件/tiaoshi/init.py”, line 8, in main

  bar(‘0’)

  代碼中第8行調(diào)用bar函數(shù)出錯(cuò),原因是第5行.

  File “F:/python文件/tiaoshi/init.py”, line 5, in bar

  return foo(s) * 2

  代碼中第5行返回foo函數(shù)出錯(cuò),原因是return 10 / int(s)這個(gè)語句出錯(cuò)了,這是錯(cuò)誤產(chǎn)生的源頭,因?yàn)橄旅娲蛴×耍?/p>

  ZeroDivisionError: integer division or modulo by zero

  根據(jù)錯(cuò)誤類型ZeroDivisionError,我們判斷,int(s)本身并沒有出錯(cuò),但是int(s)返回0,在計(jì)算10 / 0時(shí)出錯(cuò),至此,找到錯(cuò)誤源頭。

  標(biāo)題出錯(cuò)的時(shí)候,一定要分析錯(cuò)誤的調(diào)用棧信息,才能定位錯(cuò)誤的位置。

  記錄錯(cuò)誤

  如果不捕獲錯(cuò)誤,自然可以讓Python解釋器來打印出錯(cuò)誤堆棧,但程序也被結(jié)束了。既然我們能捕獲錯(cuò)誤,就可以把錯(cuò)誤堆棧打印出來,然后分析錯(cuò)誤原因,同時(shí),讓程序繼續(xù)執(zhí)行下去。Python內(nèi)置的logging模塊可以非常容易地記錄錯(cuò)誤信息:

  import logging

  def foo(s):

  return 10 / int(s)

  def bar(s):

  return foo(s) * 2

  def main():

  try:

  bar('0')

  except Exception as e:

  logging.exception(e)

  main()

  輸出結(jié)果:

  END

  ERROR:root:division by zero

  Traceback (most recent call last):

  File "F:/python文件/tiaoshi/__init__.py", line 14, in main

  bar('0')

  File "F:/python文件/tiaoshi/__init__.py", line 9, in bar

  return foo(s) * 2

  File "F:/python文件/tiaoshi/__init__.py", line 5, in foo

  return 10 / int(s)

  ZeroDivisionError: division by zero

  Python內(nèi)置的try…except…finally用來處理錯(cuò)誤十分方便。出錯(cuò)時(shí),會(huì)分析錯(cuò)誤信息并定位錯(cuò)誤發(fā)生的代碼位置才是最關(guān)鍵的。

  程序也可以主動(dòng)拋出錯(cuò)誤,讓調(diào)用者來處理相應(yīng)的錯(cuò)誤。但是,應(yīng)該在文檔中寫清楚可能會(huì)拋出哪些錯(cuò)誤,以及錯(cuò)誤產(chǎn)生的原因。

到此,相信大家對(duì)“分析Python的錯(cuò)誤,調(diào)試和測(cè)試方法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI