python異常:
python的運行時錯誤稱做異常
(1)語法錯誤:軟件的結構上有錯誤而致使不能被解釋器解釋或不能被編譯器編譯
(2)邏輯錯誤:因爲不完整或不合法的輸入所致,也多是邏輯沒法生成、計算或者輸出結果須要的過程沒法執行等html
python異常是一個對象,表示錯誤或意外狀況
(1)在python檢測到一個錯誤時,將觸發一個異常
python能夠一般異常傳導機制傳遞一個異常對象,發出一個異常狀況出現的信號
程序員也能夠在代碼中手動觸發異常
(2)python異常也能夠理解爲:程序出現了錯誤而在正常控制流之外採起的行爲
第一階段:解釋器觸發異常,此時當前程序流將被打斷
第二階段:異常處理,如忽略非致命錯誤、減輕錯誤帶來的影響等python
檢測和處理異常:
(1)異常經過try語句來檢測
任何在try語句塊裏的代碼都會被檢測,以檢查有無異常發生
(2)try語句主要有兩種形式:
try-except: 檢測和處理異常
能夠有多個except
支持使用else子句處理沒有探測異常的執行的代碼
try-finally: 僅檢查異常並作一些必要的清理工做
僅能有一個finally
(3)try語句的複合形式:
try-execpt-else-finallylinux
一、異常基礎程序員
在編程過程當中爲了增長友好性,在程序出現bug時通常不會將錯誤信息顯示給用戶,而是現實一個提示的頁面,通俗來講就是不讓用戶看見大黃頁!!!編程
try: pass except Exception as ex: pass
#python3.x中是這麼寫的,python2.x是這麼寫的: except Exception,e:python3.x
需求:將用戶輸入的兩個數字相加 ide
while True: num1 = raw_input('num1:') num2 = raw_input('num2:') try: num1 = int(num1) num2 = int(num2) result = num1 + num2 except Exception as e: print('出現異常,信息以下:') print(e)
二、異常種類函數
python中的異常種類很是多,每一個異常專門用於處理某一項異常!!!url
AssertionError: 斷言語句失敗 AttributeError: 屬性引用或賦值失敗 FloatingPointError: 浮點型運算失敗 IOError: I/O操做失敗 ImportError: import語句不能找到要導入的模塊,或者不能找到該模塊特別請求的名稱 IndentationError: 解析器遇到了一個因爲錯誤的縮進而引起的語法錯誤 IndexError: 用來索引序列的證書超出了範圍 KeyError: 用來索引映射的鍵再也不映射中 keyboardInterrupt: 用戶按了中斷鍵(Ctrl+c,Ctrl+Break或Delete鍵) MemoryError: 運算耗盡內存 NameError: 引用了一個不存在的變量名 NotImplementedError: 由抽象基類引起的異常,用於指示一個具體的子類必須覆蓋一個方法 OSError: 由模塊os中的函數引起的異常,用來指示平臺相關的錯誤 OverflowError: 整數運算的結果太大致使溢出 SyntaxError: 語法錯誤 SystemError: python自己或某些擴展模塊中的內部錯誤 TypeError:對某對象執行了不支持的操做 UnboundLocalError:引用未綁定值的本地變量 UnicodeError:在Unicode的字符串之間進行轉換時發生的錯誤 ValueError:應用於某個對象的操做或函數,這個對象具備正確的類型,但確有不適當的值 WindowsError:模塊os中的函數引起的異常,用來指示與WIndows相關的錯誤 ZeroDivisionError: 除數爲0
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
實例:IndexErrorspa
dic = ["python", 'linux'] try: dic[10] except IndexError as e: print(e)
實例:KeyError
dic = {'k1':'v1'} try: dic['k20'] except KeyError as e: print(e)
對於上述實例,異常類只能用來處理指定的異常狀況,若是非指定異常則沒法處理。
# 未捕獲到異常,程序直接報錯 s1 = 'hello' try: int(s1) except IndexError as e: print(e)
因此,寫程序時須要考慮到try代碼塊中可能出現的任意異常,能夠這樣寫:
s1 = 'hello' try: int(s1) except IndexError as e: print(e) except KeyError as e: print(e) except ValueError as e: print(e)
萬能異常 在python的異常中,有一個萬能異常:Exception,他能夠捕獲任意異常,即:
s1 = 'hello' try: int(s1) except Exception as e: print(e)
接下來你可能要問了,既然有這個萬能異常,其餘異常是否是就能夠忽略了!
答:固然不是,對於特殊處理或提醒的異常須要先定義,最後定義Exception來確保程序正常運行
s1 = 'hello' try: int(s1) except KeyError as e: print('鍵錯誤') except IndexError as e: print('索引錯誤') except Exception as e: print('錯誤')
三、異常其餘結構
try: # 主代碼塊 pass except KeyError as e: # 異常時,執行該塊 pass else: # 主代碼塊執行完,執行該塊 pass finally: # 不管異常與否,最終執行該塊 pass
四、主動觸發異常
try: raise Exception('錯誤了。。。') except Exception as e: print(e)
五、自定義異常
class MyException(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message try: raise MyException('個人異常') except WupeiqiException as e: print(e)
六、斷言
# assert 條件 assert 1 == 1 assert 1 == 2
python中的反射功能是由如下四個內置函數提供:hasattr、getattr、setattr、delattr、__import__(module_name)、importlib,改五個函數分別用於對對象內部執行:檢查是否含有某成員、獲取成員、設置成員、刪除成員、導入模塊以字符串方式導入。
class Foo(object): def __init__(self): self.name = 'python' def func(self): return 'func' obj = Foo() # #### 檢查是否含有成員 #### hasattr(obj, 'name') hasattr(obj, 'func') # #### 獲取成員 #### getattr(obj, 'name') getattr(obj, 'func') # #### 設置成員 #### setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 刪除成員 #### delattr(obj, 'name') delattr(obj, 'func')
詳細解析:
當咱們要訪問一個對象的成員時,應該是這樣操做:
class Foo(object): def __init__(self): self.name = 'python' def func(self): return 'func' obj = Foo() # 訪問字段 obj.name # 執行方法 obj.func()
class Foo(object): def __init__(self): self.name = 'python' # 不容許使用 obj.name obj = Foo()
答:有兩種方式,以下:
class Foo(object): def __init__(self): self.name = 'python' def func(self): return 'func' # 不容許使用 obj.name obj = Foo() print obj.__dict__['name']
第二種:
class Foo(object): def __init__(self): self.name = 'python' def func(self): return 'func' # 不容許使用 obj.name obj = Foo() print getattr(obj, 'name')
d、比較三種訪問方式
答:第一種和其餘種比,...
第二種和第三種比,...
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server class Handler(object): def index(self): return 'index' def news(self): return 'news' def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] temp = url.split('/')[1] obj = Handler() is_exist = hasattr(obj, temp) if is_exist: func = getattr(obj, temp) ret = func() return ret else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8001, RunServer) print "Serving HTTP on port 8000..." httpd.serve_forever()
結論:反射是經過字符串的形式操做對象相關的成員。一切事物都是對象!!!
類也是對象
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print getattr(Foo, 'staticField') print getattr(Foo, 'func') print getattr(Foo, 'bar')
模塊也是對象
home.py
#!/usr/bin/env python # -*- coding:utf-8 -*- def dev(): return 'dev'
index.py
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 程序目錄: home.py index.py 當前文件: index.py """ import home as obj #obj.dev() func = getattr(obj, 'dev') func()
第一個例子:模塊和主程序在同一目錄
home.py
#!/usr/bin/env python # -*- coding:utf-8 -*- def index(): print("炫酷的主頁面")
index.py
#!/usr/bin/env python # -*- coding:utf-8 -*- # 反射:基於字符串的形式去對象(模塊)中操做其成員getattr(),setattr(),hasattr(),delattr() # 擴展:導入模塊 # import xxx # from xxx import ooo # # obj = __import__("xxx") # obj = __import__("xxx." + ooo,fromlist=True) def run(): while True: inp = input("請輸入要訪問的URL:") mo,fn = inp.split('/') obj = __import__(mo) if hasattr(obj,fn): func = getattr(obj,fn) func() else: print("網頁不存在") run()
執行的時候輸入URL:home/index 這樣就執行了home模塊下的index函數
第二個例子:模塊和主程序不在同一目錄
lib/account.py
#!/usr/bin/env python # -*- coding:utf-8 -*- def login(): print("炫酷的登陸頁面") def logout(): print("炫酷的退出頁面")
index1.py
#!/usr/bin/env python # -*- coding:utf-8 -*- # 反射:基於字符串的形式去對象(模塊)中操做其成員getattr(),setattr(),hasattr(),delattr() # 擴展:導入模塊 # import xxx # from xxx import ooo # # obj = __import__("xxx") # obj = __import__("xxx." + ooo,fromlist=True) def run(): while True: inp = input("請輸入要訪問的URL:") mo,fn = inp.split('/') obj = __import__("lib." + mo,fromlist=True) if hasattr(obj,fn): func = getattr(obj,fn) func() else: print("網頁不存在") run()
執行的時候輸入URL:account/login 這樣就執行了lib/account下的login函數
### 另一種實現方式
index2.py
import importlib module = "lib.account" func_name = "login" m = importlib.import_module(module) func = getattr(m, func_name) func()
利用反射和super()的一個例子:點這裏