裝飾器本質上是乙個python函式,它可以讓其他函式在不需要做任何**邊動的前提下增加額外的功能,裝飾器返回值也是乙個函式物件。簡單來說,裝飾器的作用就是為已經存在的物件新增額外的功能。
裝飾器分為幾種
簡單裝飾器:
def
use_logging
(func):
def(*args,**kwargs):
logging.warn("%s is running"% func.__name__)
return func(*args,**kwargs)
defbar
(): print('i am bar')
bar = use_logging(bar)
bar()
函式use_logging就是裝飾器,它把執行真正業務方法的func包裹在函式裡面,看起來像bar被use_logging裝飾了。在這個例子中,函式進入和退出時 ,被稱為乙個橫切面(aspect),這種程式設計方式被稱為面向切面的程式設計(aspect-oriented programming)。
@符號是裝飾器的語法糖,在定義函式的時候使用,避免再一次賦值操作。
def
use_logging
(func):
def(*args,**kwargs):
logging.warn("%s is running"% func.__name__)
return func(*args,**kwargs)
@use_logging
defbar
(): print('i am bar')
deffoo
(): print("i am foo")
bar()
如上所示,這樣我們就可以省去bar = use_logging(bar)這一句了,直接呼叫bar()即可得到想要的結果。
帶引數裝飾器:
裝飾器還有更大的靈活性,例如帶引數的裝飾器:在上面的裝飾器呼叫中,比如@use_logging,該裝飾器唯一的引數就是執行業務的函式。裝飾器的語法允許我們在呼叫時,提供其它引數,比如@decorator(a)。這樣,就為裝飾器的編寫和使用提供了更大的靈活性。
def
use_logging
(level):
defdecorator
(func):
def(*args,**kwargs):
if level == "warn"
logging.warn("%s is running"% func.__name__)
return func(*args)
return decorator
@use_logging(level="warn")
deffool
(name='foo'):
print('i am bar')
foo()
上面的use_logging是允許帶引數的裝飾器。它實際上是對原有裝飾器的乙個函式封裝,並返回乙個裝飾器。我們可以將它理解為乙個含有引數的閉包。當我 們使用@use_logging(level=」warn」)呼叫的時候,python能夠發現這一層的封裝,並把引數傳遞到裝飾器的環境中。
類裝飾器:
再來看看類裝飾器,相比函式裝飾器,類裝飾器具有靈活度大、高內聚、封裝性等優點。使用類裝飾器還可以依靠類內部的__call__方法,當使用 @ 形式將裝飾器附加到函式上時,就會呼叫此方法。
class
foo(object):
def__init__
(self, func):
self._func = func
def__call__
(self):
print ('class decorator runing')
self._func()
print ('class decorator ending')
@foo
defbar
():print ('bar')
bar()
使用裝飾器極大地復用了**,但是他有乙個缺點就是原函式的元資訊不見了,比如函式的docstring、name、引數列表
內建裝飾器:
@staticmathod、@classmethod、@property
裝飾器的順序
@a
@b@c
deff
():
等效於
f =a(b(c(f)))
常用python異常
assertionerror:當assert斷言條件為假的時候丟擲的異常
attributeerror:當訪問的物件屬性不存在的時候丟擲的異常
indexerror:超出物件索引的範圍時丟擲的異常
keyerror:在字典中查詢乙個不存在的key丟擲的異常
nameerror:訪問乙個不存在的變數時丟擲的異常
oserror:作業系統產生的異常
syntaxerror:語法錯誤時會丟擲此異常
typeerror:型別錯誤,通常是不通型別之間的操作會出現此異常
zerodivisionerror:進行數**算時除數為0時會出現此異常
indentationerror:縮排錯誤
示例:
try:
正常的操作
.........
......
......
.except(exception1[, exception2[,...exceptionn]
]]):
發生以上多個異常中的乙個,執行這塊**
......................
else:
如果沒有異常執行這塊**
如果乙個函式有多個錯誤,則從上往下執行,如果執行錯誤,則報錯,後面另外的錯誤不會執行。
製作自己的異常
1、編寫自己的異常時,通常是繼承exception
2、如果繼承的是baseexception,那麼就不會被通用的except exception捕捉到
3、自己定義的異常python不會自動觸發,需要自己觸發,用raise進行觸發
4、python只會自動觸發它自己本身內建的異常,如indexeerror,nameerror,ioerror等,只要是error結尾通常都是內建異常
class
myexception
(exception):
def__init__
(self, msg):
#msg引數用於接收自己觸發異常時傳進來的錯誤描述資訊
self.msg = msg
def__str__
(self):
#格式化輸出
return
"[internal logic error:] %s" % (self.msg)
if __name__ == '__main__':
flag = false
try:
if flag:
print("initialization data")
print("done...")
else:
raise myexception("no data") #觸發自己的異常
except myexception as err: #捕捉被觸發的自定義異常
print(err) #列印異常資訊,如果有引數,那麼可通過err.args列印引數
try….finally
finally:無論try是否丟擲異常,永遠執行finally後**
try:
......
......
......
.finally:
......
......
......
python3之裝飾器學習
def 外部函式 引數 def 內部函式 pass return 內部函式 外部函式 def test passdef set fun func def call fun print 許可權認證 func return call fun set fun test set fun test def t...
python3 深入裝飾器
def outer c def inner uname print 我是 end c uname return inner outer def fun 1 uname print f 北京的 fun 1 mike def outer c def inner args,kwargs 通用的形參的設定 ...
Python3 高階 裝飾器
1.裝飾器功能 在不修改原函式的情況下,增強函式功能 2.不帶引數的函式 不帶引數的裝飾器 1 foo 被裝飾的函式 2 show time 是裝飾器 coding utf 8 import time def show time func def inner start time time.time...