標籤:name war 輸入 對象 標識 alt 操作 設計 執行
一、閉包1、如果一個函數定義在另一個函數的範圍內,並且引用了外層函數的變數,則該函數稱為閉包。def outter():name=‘python‘def inner():print namereturn innerres=outter() 把inner的地址賦值給resres() 相當於執行inner()函數。通過閉包,可以把局部變數在外部也可以使用2、判斷是否為閉包 res.func_closureinner()函數就是一個閉包3、通過閉包,可以把局部變數在外部也可以使用 二、裝飾器 @開始的裝飾器屬於閉包,把一個函數當做參數後返回一個替代版函數。1、定義在代碼運行期間在不改變原函數定義的基礎上,動態給該函數增加功能的方式,稱之為裝飾器(Decorator) 裝飾器的具體定義:1、把要裝飾的方法作為輸入參數;2、在函數體內可以進行任意的操作(可以想象其中會有很多應用情境);3、只要確保最後返回一個可執行檔函數即可(可以是原來的輸入參數函數,也可以是一個新函數)。 作用:裝飾器是一個很著名的設計模式,較為經典的有插入日誌、效能測試、交易處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量函數中與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能。總體來說,裝飾器其實也是一個函數,一個用來封裝函數的函數,返回一個修改之後的函數對象,將其重新賦值給原來的標識符,並永久喪失對原始函數對象的訪問。(1)不帶參數的裝飾器eg: ( @log裝飾器)#定義裝飾器def log(func):def wrapper(*args,**kwargs):print ‘call %s‘%func.__name__return func(*args,**kwargs) return原函數,是為了返回保證原函數的傳回值return wrapper 解釋:因為有了(*args, **kw)這樣的參數格式,這意味著裝飾器能夠接受擁有任何簽名的函數作為自己的被裝飾方法,同時能夠用傳遞給它的參數對被裝飾的方法進行調用。這樣就能處理參數個數不同的函數了。 @log # 調用了log函數,並把now賦值給了log作為參數 @log = log(now)def now():now = time.strftime(‘%Y-%m-%d %H:%M:%S‘,time.localtime())print ‘current time is %s‘%nownow() # now() == wraper()如果now帶有參數:now(2,3) @log =log(now) now(2,3)=log(now)(2,3) @log的傳回值是wrapper 所以 now(2,3)=wrapper(2,3) 對於函數的又一次理解:now() 相當於執行了now這個函數,ret=now() 相當於執行了now函數後,把傳回值賦值給了ret(2)帶參數的裝飾器def deco(arg): def _deco(func): def __deco(): print "before %s called [%s]." % (func.__name__, arg) func() print " after %s called [%s]." % (func.__name__, arg) return __deco return _deco@deco("mymodule")def myfunc(): print " myfunc() called."@deco("module2")def myfunc2(): print " myfunc2() called."myfunc()myfunc2() 2、python內建的三個裝飾器@classmethod 定義執行個體方法為類方法@staticmethod 定義執行個體方法為靜態方法@porperty 屬性(對類屬性的操作) 3、優點和用途抽離出大量函數中與函數功能本身無關的的雷同代碼並繼續重用。使用裝飾器可以將函數“修飾”為完全不同的行為,可以有效將商務邏輯正交分解,如用於將許可權與身分識別驗證從業務中獨立出來。如果一個函數需要一個功能,如果這個功能可以被使用在很多函數上,或是函數並不是自己實現,那可以寫個裝飾器來實現這些功能。概況的將,裝飾器的作用就是為已經存在的對象添加一些額外的功能。
Python之物件導向:閉包和裝飾器