Python之decorator,閉包,異常

2021-07-15 03:39:38 字數 2868 閱讀 7509

#裝飾器,類似物件導向設計模式裡的靜態**模式

'''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)

作用 假設我們有乙個使用了八個物件的程式,由於需求變更,其中三個物件需要另外乙個屬性。讀者可以為這三個物件建立乙個派生類,在多數情況下,這是乙個完全可以接受的方案。然而,如果這三個物件中的每個物件都要求有不同的屬性,這就意味著要建立三個派生類。更進一步,如果其中乙個類具有其他兩個類中的屬性,可能就要...