所謂閉包簡單點說就是定義乙個函式,這個函式裡面還有乙個函式,此時裡面的函式和外面函式中的變數之間就產生了閉包關係。
# 定義乙個函式def test(num):
# 裡面還有乙個函式
def test_inner(num_inner): # 這個函式和外面函式的變數num之間就產生了閉包
print(num + num_inner)
return test_inner
fun = test(10)
fun(10)
fun(20)
以上**執行的結果是:20和30
從執行的結果可以看出,當test(10)執行完畢之後函式裡面的num變數並沒有隨著函式執行完畢而銷毀,而是一直保留著這個變數。正因為這種特性我們可以在一些計算中將外面函式中定義的變數作為基值進行計算。下面看乙個具體的例項:
def linetest(a, b):# line_inner和a,b產生了閉包關係
def line_inner(x):
return a*x + b
return line
line = linetest(1, 1)
print(line(5))
print(line(4))
這個例子中,我們通過linetest的引數a,b來確定直線表示式的取值,最準確定函式的形式(y = x + 1)。此時的未知數是x,那麼為了得到不同的方程我們只需要改變x的值就可以了。沒必要每次呼叫給都傳遞a和b兩個引數的值。這樣我們的**有很好的可讀性和可移植性,還能提高**的復用性。
我們在開發系統時有些介面的呼叫往往需要進行驗證呼叫者的許可權的,具體的做法就是在介面呼叫之前來判斷一下是否有許可權。那麼想一下把判斷的這一部分**放在什麼地方比較合適(肯定不會放在每乙個介面中,沒人會這麼幹對吧。),那麼放在那裡比較合適呢?
類似的例子還有很多,比如方法中列印日誌,方法呼叫完成之後做一些清理操作等等。
那麼裝飾器就是來解決這類問題的。首先看一下下面的例子:
def check(func):def oper():
print "完成驗證操作的邏輯"
func()
return oper
def update_user():
print "修改使用者資訊"
def delete_user():
print "刪除使用者資訊"
check(update_user)() # 1
check(delete_user)() # 2
執行結果:
完成驗證操作的邏輯
修改使用者資訊
完成驗證操作的邏輯
刪除使用者資訊
上面的**中將許可權驗證的**寫在了oper函式中。
第一步和第二步函式呼叫部分為了看得清楚一點其實python提供了更簡潔的呼叫的方法。如下:
def check(func):def oper():
print "完成驗證操作的邏輯"
func()
return oper
@check
def update_user():
print "修改使用者資訊"
@check
def delete_user():
print "刪除使用者資訊"
update_user()
delete_user()
其實道理和上面的呼叫方式一樣的。這樣就很好解決了**的冗餘和復用性。
python閉包以及裝飾器
通俗的定義 如果在乙個內部函式裡,對在外部作用域 但不是在全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 它只不過是個 內層 的函式,由乙個名字 變數 來指代,而這個名字 變數 對於 外層 包含它的函式而言,是本地變數 1 示例一 2 usr bin python 3 en...
python閉包以及裝飾器
閉包 簡單理解 所謂閉包簡單點說就是定義乙個函式,這個函式裡面還有乙個函式,此時裡面的函式和外面函式中的變數之間就產生了閉包關係。理解 def test num 裡面還有乙個函式 def test inner num inner 這個函式和外面函式的變數num之間就產生了閉包 print num n...
Python 裝飾器 ,閉包
1 裝飾器 不改變被裝飾的函式情況下附加一些功能 本質是函式,用於裝飾其他函式,附加一些本身所沒有的功能 實質 是乙個函式 引數 是你要裝飾的函式名 並非函式呼叫 返回 是裝飾完的函式名 也非函式呼叫 作用 為已經存在的物件新增額外的功能 特點 不需要對物件做任何的 上的變動 例1 計算執行時長 i...