第二篇,來說說裝飾器,在介紹裝飾器之前先要理解閉包的概念。
閉包
內部函數對外部環境變量(但不是全局作用域變量)進行引用,內部函數就是一個閉包。
- 條件1:內部函數
- 條件2:外部環境變量
閉包就是滿足這兩個條件的函數
注意:閉包中不能修改外部作用域的局部變量
程序示例:
def addbase(x):
def addp(y):
return x+y
return addp
f=addbase(10)
print(f(8))
print(addbase(10)(9))
運行結果:
18
19
說完閉包,理解裝飾器就比較簡單了。
裝飾器
裝飾器(decorator)可以用來增強函數的功能,同時不改變原函數的定義,使用起來非常方便。
程序示例1:
#在不改變sum_1函數的基礎上我們希望加入附加功能,
#檢驗參數,當參數爲負數時,返回零值
def dec_1(func):
def jianyan(num1,num2):
#參數檢驗
if num1<0 or num2<0:
print("參數最好不要小於0")
return 0
return func(num1,num2)
return jianyan
#定義普通函數
def sum_1(num1,num2):
return (num1+num2)
sum_1=dec_1(sum_1)
print(sum_1(-2,0))
print(sum_1(5,4))
運行結果:
參數最好不要小於0
0
9
上面的定義過程略顯複雜,Python提供了更加簡潔方便的方式,使用@,上面的程序可以改寫爲下面這樣,功能不變:
def dec_1(func):
def jianyan(num1,num2):
#參數檢驗
if num1<0 or num2<0:
print("參數最好不要小於0")
return 0
return func(num1,num2)
return jianyan
#使用@語法糖的方式
@dec_1
#定義普通函數
def sum_1(num1,num2):
return (num1+num2)
#sum_1=dec_1(sum_1)
print(sum_1(-2,0))
print(sum_1(5,4))
程序運行結果和上面保持一致:
參數最好不要小於0
0
9
裝飾器還可以使用更加通用的定義方式,去裝飾各種類型的函數,在這裏僅僅用於演示我們寫了一個比較簡單的例子,用裝飾器去輸出每個函數的參數。
def dec_2(func):
def printer(*args, **kwargs):
print("參數是:%s,%s"%(args, kwargs))
return(func(*args, **kwargs))
return printer
@dec_2
def sum(num1,num2):
#求和
return num1+num2
@dec_2
def fool(num1,num2,num3):
#取最後一個參數返回
return num3
print(sum(1,2))
print(fool(6,7,8))
運行結果:
參數是:(1, 2),{}
3
參數是:(6, 7, 8),{}
8