程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python閉包、裝飾器、語法糖

編輯:Python

函數高級的用法,本文將使用案例來講解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

裝飾器

就是給已有函數增加額外功能的函數,它本質上就是一個閉包函數。

裝飾器的功能特點:

  1. 不修改已有函數的源代碼
  2. 不修改已有函數的調用方式
  3. 給已有函數增加額外的功能

裝飾器的基本雛形

# 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)

裝飾器的執行時間是加載模塊時立即執行。

代碼說明:

  • 閉包函數有且只有一個參數,必須是函數類型,這樣定義的函數才是裝飾器。
  • 寫代碼要遵循開放封閉原則,它規定已經實現的功能代碼不允許被修改,但可以被擴展。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved