#裝飾器,類似物件導向設計模式裡的靜態**模式
'''python的 decorator 本質上就是乙個高階函式,它接收乙個函式作為引數,然後,返回乙個新函式。
使用 decorator 用python提供的 @ 語法,這樣可以避免手動編寫 f = decorate(f) 這樣的**。
'''def log(f):
def fn(x):
print 'call ' + f.__name__ + '()...'
return f(x)
return fn
@log
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
執行結果:
call factorial()...
3628800
但如果被裝飾的函式有多個引數,則要換個寫法。
def log2(f):
'''*args 容納任意變數的list
**kw 容納任意key,value的dict
'''def fn(*args, **kw):#可接收任何引數
print 'call ' + f.__name__ + '()...'
return f(*args, **kw)
return fn
@log2
def add(x, y):
return x + y
print add(1, 2)
執行結果:
call add()...
3
但如果裝飾器需要傳參,則又得改**:
import time
def performance(unit):
def cget(fc): #以此來傳fc
def gtime(*args, **kw):
if unit == 'ms':
lt = int(round(time.clock()*1000))
fv = fc(*args, **kw)
print 'call %s() in %d ms' % (fc.__name__, int(round(time.time()*1000))-lt)
return fv
return gtime
return cget
#含引數的裝飾器
@performance('ms')
def factoriall(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factoriall(10)
執行結果:
call factoriall() in 1468813702849 ms
3628800
裝飾器的邏輯很簡單,就是在某段操作執行前做一些事,類似aop的前置通知。可以將一些共性操作提取出來,作為裝飾者。
內層函式引用了外層函式的變數(引數也算變數),然後返回內層函式的情況,稱為閉包(closure)。
閉包的特點就是內層函式引用了外層函式的區域性變數,所以,要正確使用閉包,就要確保引用的區域性變數在函式返回後不能變。
至於閉包,有個經典栗子。
def count():
fs =
for i in range(1, 4):
def f():
return i*i
return fs
f1, f2, f3 = count()
print f1(),f2(),f3()
執行結果:
9 9 9
因為最終i已成為3,可作如下修改:
def count1():
fs =
for i in range(1, 4):
def f(m=i):
return m*m
return fs
f1, f2, f3 = count1()
print f1(),f2(),f3()
執行結果:
1 4 9
異常處理就簡單舉個栗子:
try:
a = 8/0
except exception,ex:
print exception,":",ex
執行結果:
: integer division or modulo by zero
python中編寫無引數decorator
python的 decorator 本質上就是乙個高階函式,它接收乙個函式作為引數,然後,返回乙個新函式。使用 decorator 用python提供的 語法,這樣可以避免手動編寫 f decorate f 這樣的 考察乙個 log的定義 def log f deffn x print call f...
23種設計模式之裝飾模式(Decorator)
裝飾模式是一種物件結構型模式,可動態地給乙個物件增加一些額外的職責,就增加物件功能來說,裝飾模式比生成子類實現更為靈活。通過裝飾模式,可以在不影響其他物件的情況下,以動態 透明的方式給單個物件新增職責 當需要動態地給乙個物件增加功能,這些功能可以再動態地被撤銷時可使用裝飾模式 當不能採用生成子類的方...
設計模式學習之裝飾者模式(Decorator)
作用 假設我們有乙個使用了八個物件的程式,由於需求變更,其中三個物件需要另外乙個屬性。讀者可以為這三個物件建立乙個派生類,在多數情況下,這是乙個完全可以接受的方案。然而,如果這三個物件中的每個物件都要求有不同的屬性,這就意味著要建立三個派生類。更進一步,如果其中乙個類具有其他兩個類中的屬性,可能就要...