函數高級的用法,本文將使用案例來講解Python閉包、裝飾器、語法糖。
我們前面已經學過了函數,我們知道當函數調用完,函數內定義的變量都銷毀了,但是我們有時候需要保存函數內的這個變量,每次在這個變量的基礎上完成一些列的操作,比如: 每次在這個變量的基礎上和其它數字進行求和計算,那怎麼辦呢?
我們就可以通過咱們今天學習的閉包來解決這個需求。
在函數嵌套的前提下,內部函數使用了外部函數的變量,並且外部函數返回了內部函數,我們把這個使用外部函數變量的內部函數成為閉包
通過閉包的定義,我們可以得知閉包的形成條件:
閉包的作用
:
閉包可以保存外部函數內的變量,不會隨著外部函數調用完而銷毀。
由於閉包引用了外部函數的變量,則外部函數的變量沒有及時釋放,消耗內存。
def out(num1): # 定義一個外部函數
def inner(num2): #定義一個內部函數
result = num1 + num2 # 內部函數使用了外部函數num1
print("結果是:", result)
return inner # 外部函數返回內部函數,這裡返回的內部函數就是閉包
#創建閉包實例
f = out(1)
f(2)
f(3)
結果是: 3
結果是: 4
通過上面的輸出結果可以看出閉包保存了外部函數內的變量num1,每次執行閉包都是在num1 = 1 基礎上進行計算。
簡單例子
# 外部函數
def config_name(name):
# 內部函數
def say_info(info):
print(name + ": " + info)
return say_info
tom = config_name("Tom")
tom("你好!")
tom("你好, 在嗎?")
jerry = config_name("jerry")
jerry("不在, 不和玩!")
Tom: 你好!
Tom: 你好, 在嗎?
jerry: 不在, 不和玩!
閉包還可以提高代碼的可重用性,不需要再手動定義額外的功能函數。
修改閉包內使用的外部函數變量使用 nonlocal
關鍵字來完成
def out(num1):
def inner(num2):
# 這裡本意想要修改外部num1的值,實際上是在內部函數定義了一個局部變量num1
nonlocal num1 #修改外部變量num1
num1 = 10
result = num1 + num2
print(f'結果是:{
result}')
return inner
f1 = out(1)
f(2)
結果是: 12
就是給已有函數增加額外功能的函數,它本質上就是一個閉包函數。
裝飾器的功能特點
:
裝飾器的基本雛形
# def decorator(fn): # fn:目標函數.
# def inner():
# '''執行函數之前'''
# fn() # 執行被裝飾的函數
# '''執行函數之後'''
# return inner
實例
# 添加一個登錄驗證的功能
def check(fn):
def inner():
print("請先登錄....")
fn()
return inner
def comment():
print("發表評論")
# 使用裝飾器來裝飾函數
comment = check(comment)
comment()
請先登錄....
發表評論
顯然,這樣來調用比較麻煩,因此引入了語法糖的概念
裝飾器的語法糖
寫法
# 添加一個登錄驗證的功能
def check(fn):
print("裝飾器函數執行了")
def inner():
print("請先登錄....")
fn()
return inner
# 使用語法糖方式來裝飾函數
@check
def comment():
print("發表評論")
comment()
裝飾器函數執行了
請先登錄....
發表評論
說明:
@check 等價於comment = check(comment)
裝飾器的執行時間是加載模塊時立即執行。
代碼說明: