1. 程式人生 > 程式設計 >Python異常原理及異常捕捉實現過程解析

Python異常原理及異常捕捉實現過程解析

關於選課程式,最近著實有點忙,沒機會複習os、pickle兩部分模組,所以資料儲存和字典讀取成為了一個問題,大致原理知道,但是具體操作可能還是得返回去再好好看看,所以目前就提前開始學習新的知識了,雖然今天感覺str的相關方法忘的是乾乾淨淨的,但是我有pycharm。

今天主要內容是關於異常,其實有點想最開始剛學的感覺,比較簡單。

  異常就是程式執行時發生錯誤的訊號(在程式出現錯誤時,則會產生一個異常,若程式沒有處理它,則會丟擲該異常,程式的執行也隨之終止),在python中,錯誤觸發的異常如下:

Python異常原理及異常捕捉實現過程解析

  錯誤被分為了兩種:

  1.語法錯誤,基本pycharm都會幫你顯示出來,不該犯的

  2.邏輯錯誤,不太容易看出來,pycharm也不管,只有Python直譯器是真愛,但是也得等到真的執行的時候

#TypeError:int型別不可迭代
for i in 3:
  pass
#ValueError
num=input(">>: ") #輸入hello
int(num)

#NameError
aaa

#IndexError
l=['egon','aa']
l[3]

#KeyError
dic={'name':'egon'}
dic['age']

#AttributeError
class Foo:pass
Foo.x

#ZeroDivisionError:無法完成計算
res1=1/0
res2=1+'str'

  下面是今天最為重要的部分:

  在python中不同的異常可以用不同的型別(python中統一了類與型別,型別即類)去標識,一個異常標識一種錯誤

AttributeError 試圖訪問一個物件沒有的樹形,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法開啟檔案
ImportError 無法引入模組或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;程式碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典裡不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予物件的變數
SyntaxError Python程式碼非法,程式碼不能編譯(個人認為這是語法錯誤,寫錯了)

TypeError 傳入物件型別與要求的不符合
UnboundLocalError 試圖訪問一個還未被設定的區域性變數,基本上是由於另有一個同名的全域性變數,
導致你以為正在訪問它
ValueError 傳入一個呼叫者不期望的值,即使值的型別是正確的

  更多異常(有空還是要挨個錯一遍):

ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError

  為了保證程式的健壯性與容錯性,即在遇到錯誤時程式不會崩潰,我們需要對異常進行處理,

   如果錯誤發生的條件是可預知的,我們需要用if進行處理:在錯誤發生之前進行預防

  之前也是有操作過的:

AGE=10
while True:
  age=input('>>: ').strip()
  if age.isdigit(): #只有在age為字串形式的整數時,下列程式碼才不會出錯,該條件是可預知的
    age=int(age)
    if age == AGE:
      print('you got it')
      break

如果錯誤發生的條件是不可預知的,則需要用到try...except:在錯誤發生之後進行處理

#基本語法為
try:
  被檢測的程式碼塊
except 異常型別:
  try中一旦檢測到異常,就執行這個位置的邏輯
#舉例
try:
  f=open('a.txt')
  g=(line.strip() for line in f)
  print(next(g))
  print(next(g))
  print(next(g))
  print(next(g))
  print(next(g))
except StopIteration:
  f.close()
#1 異常類只能用來處理指定的異常情況,如果非指定異常則無法處理。
s1 = 'hello'
try:
  int(s1)
except IndexError as e: # 未捕獲到異常,程式直接報錯
  print e

#2 多分支
s1 = 'hello'
try:
  int(s1)
except IndexError as e:
  print(e)
except KeyError as e:
  print(e)
except ValueError as e:
  print(e)

#3 萬能異常Exception
s1 = 'hello'
try:
  int(s1)
except Exception as e:
  print(e)

#4 多分支異常與萬能異常
#4.1 如果你想要的效果是,無論出現什麼異常,我們統一丟棄,或者使用同一段程式碼邏輯去處理他們,那麼騷年,大膽的去做吧,只有一個Exception就足夠了。
#4.2 如果你想要的效果是,對於不同的異常我們需要定製不同的處理邏輯,那就需要用到多分支了。

#5 也可以在多分支後來一個Exception
s1 = 'hello'
try:
  int(s1)
except IndexError as e:
  print(e)
except KeyError as e:
  print(e)
except ValueError as e:
  print(e)
except Exception as e:
  print(e)

#6 異常的其他機構
s1 = 'hello'
try:
  int(s1)
except IndexError as e:
  print(e)
except KeyError as e:
  print(e)
except ValueError as e:
  print(e)
#except Exception as e:
#  print(e)
else:
  print('try內程式碼塊沒有異常則執行我')
finally:
  print('無論異常與否,都會執行該模組,通常是進行清理工作')

#7 主動觸發異常
try:
  raise TypeError('型別錯誤')
except Exception as e:
  print(e)

#8 自定義異常
class EgonException(BaseException):
  def __init__(self,msg):
    self.msg=msg
  def __str__(self):
    return self.msg

try:
  raise EgonException('型別錯誤')
except EgonException as e:
  print(e)

#9 斷言:assert 條件
assert 1 == 1 
assert 1 == 2

#10 總結try..except

異常捕捉的優勢:

1:把錯誤處理和真正的工作分開來

2:程式碼更易組織,更清晰,複雜的工作任務更容易實現;

3:毫無疑問,更安全了,不至於由於一些小的疏忽而使程式意外崩潰了;

主要是理論知識,後期使用才是關鍵,就像我要複習的pickle和os模組一樣,就是這些了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。