程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Python >> python 裝飾器、內部函數、閉包簡單理解

python 裝飾器、內部函數、閉包簡單理解

編輯:Python

python內部函數、閉包共同之處在於都是以函數作為參數傳遞到函數,不同之處在於返回與調用有所區別。

1、python內部函數

python內部函數示例:

def test(*args):
    def add(*args):         #  顯示的調用外部函數的參數
        return args
    return add(*args)       #  返回內部函數的直接調用

運行結果如下:
test(1,2,3)
(1,2,3)    

 
內部函數直接引用外部函數參數,外部函數test顯示的返回內部函數add的調用。
當需要在函數內部多次執行復雜任務時,內部函數非常有用,從而避免了循環和代碼的堆疊重復。

 

2、python閉包

內部函數可以看作是一個閉包。閉包是一個可以由另一個函數動態生成的函數,並且可以改變和存儲函數外創建的變量的值。


python閉包示例:

def test(a):
    def add():                                #  沒用引用外部函數的參數
        return "it's a callable %s" % a       #  直接在內部函數使用外部函數的參數
    return add                                #  返回內部函數本身,不返回內部函數調用

運行結果如下:
a1 = test(1)           # 動態生成的一個可以記錄外部變量的函數
<function __main__.add>

a1()                   # 調用此函數
it's a callable 1

test(1)()              # 本身調用過程,先動態生成一個函數再進行調用
it's a callable 1

 

3、python裝飾器

裝飾器實質上是一個函數,它把一個函數作為輸入並且返回另外一個函數,在裝飾器中,通常使用下面這些python技巧:

  • *args 和 **kwargs

  • 閉包

  • 作為參數的函數

python裝飾器示例:

def test(func):                           # 將函數作為參數進行傳遞
    def add(*args,**kwargs):
        print “it's a d”
        return func(*args,**kwargs)       # 內部函數進行相關操作以後,返回傳遞函數的調用
    return add


def func(a,b):
    return a+b

運行結果如下:
test(func)                # 將func作為函數傳遞進test函數進行裝飾
<function __main__.add>   # 裝飾後的函數,類似閉包

test(func)(1,2)           # 顯示的對裝飾後的函數進行調用
it's a d                  # 中間被裝飾的過程被print出來
3

更簡單的方法調用裝飾器
@test                     # 同一個函數可以調用多個裝飾器,執行過程中不分先後順序
def func(a,b):
    return a+b

無論傳入test()的函數func是什麼,裝飾器都會返回一個新的函數,其中包含test增加的額外語句。
實際上,裝飾器並不需要執行函數func中的代碼,只是在結束前函數add調用函數func以得到的func返回的結果和附加代碼的結果

 裝飾器本身需要傳遞參數的時候:

def test(cmd):                            # 將參數傳遞
    def exc(func):                        # 第二步進行函數作為參數傳遞
         def add(*args,**kwargs):
             print "it's a %s" % cmd
             print "begin"
             return func(*args,**kwargs)
         return add
    return exc
 
 運行結果如下:
 test('haha')
 <function __main__.exc>
 
 test('haha')(func)(1,2)            # 調用裝飾器返回結果
 it's a haha
 begin
 3
 
 更簡單的方法調用
 @test('haha')                     # test函數進行了參數傳遞
 def func(a,b):
    return a+b

 python裝飾器注意事項:
對func進行裝飾以後,func的函數命名空間發生了變化

執行 func.__name__
add

 如何指向原來的命名空間呢?python自帶了functools庫直接調用則行

import functools
def test(func):
    @functools.wraps(func)
    def add(*args,**kwargs):
        print "it's a decorator"
        return func(*args,**kwargs)
    return add
    
@test
def func(a,b):
    return a+b
    
再次運行,查看命名空間
func.__name__
func                  # 返回了本身
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved