一文掌握Python內部函數:函數作為返回和閉包

2025年03月17日02:33:07 科技 1510

一文掌握Python內部函數:函數作為返回和閉包 - 天天要聞

Python 中,函數被認為是一等公民,這意味著它們可以像對待任何其他對象一樣對待。這種對一類函數的支持允許使用高階函數,這些函數可以接受其他函數作為參數或返回函數作為結果。這個強大的功能增強了 Python 編程的靈活性和表現力,允許更動態和功能化的編程模式。

為了理解為什麼這些能力是有用的,編寫一個返回其參數的恆等式函數。

def identity(number): 
  return number

identity(10)

#10

現在編寫另一個函數來求平方。

def square(number):
  return number**2

square(6)

#36

現在,將這兩種功能組合到一個函數中。為此,可以將這兩個函數編寫為另一個函數的內部函數。

Python 內部函數:

在 Python 中,內部函數是在另一個函數的主體中定義的函數。它也稱為嵌套函數。們的例子中:

def doWithNumber(number, squareIt = False):

  # identity function as inner function of doWithTheNumber
  def identity(): 
    return number

  # square function as inner function of doWithTheNumber
  def square():
    sq = number**2
    return sq

  # if else block to execute one of the function
  if squareIt == True:
    return square()
  else:
    return identity()

內部函數的作用域在外部函數內,這意味著它可以訪問外部函數的變數和參數。

在上面的例子中, identity()square() 被定義在 doWithNumber(number, squareIt= False) .內部函數可以訪問外部函數的變數和參數,例如,兩者都 i可以訪問 number ,但反之則不然, doWithNumber(number, squareIt= False) 無權訪問 哪個是 的內部變數 square() 。這稱為詞法範圍或閉包。

內部函數在各種場景中都很有用,例如:

  1. 封裝:內部函數允許我們將一個功能封裝在另一個函數的範圍內,將相關代碼保持在一起並與程序的其餘部分分開。上面的函數 doWithNumber(number, squareIt= False) 是封裝的一個很好的例子。
  2. 閉包:內部函數可以創建閉包,這些函數可以記住封閉範圍內的值,即使它們不再存在。這允許在函數調用之間保留狀態。
  3. 裝飾器:內部函數通常用於裝飾器中,這是一種通過用附加功能包裝函數或類來修改它們的行為的方法。內部函數用作包裝器,將所需的功能添加到原始函數中。

返回函數和閉包:

一個函數可以返回另一個函數。例如,可以稍微修改我們的 modifyNumber 數字函數以返回內部函數而不是執行它們。

def modifyNumber(squareIt = False):

  # identity function as inner function of doWithTheNumber
  def identity(number): 
    return number

  # square function as inner function of doWithTheNumber
  def square(number):
    sq = number**2
    return sq

  # if else block to execute one of the function
  if squareIt == True:
    return square
  else:
    return identity

現在,如果執行外部函數,這將為提供另一個函數。請記住,它不會執行任何函數,而是會提供另一個可執行函數。

justPrint = modifyNumber()

上面的代碼將返回我們內部函數 identity(number) 。現在我以用參數調用 justPrint 了。

justPrint(15)

#15

Or

squareNumber= modifyNumber(True)

squareNumber(25)

#625

這裡發生了什麼?

首先,當調用 squareNumber = modifyNumber(True) 它時,它會設置 squareIt = True .

然後它定義了我們的兩個函數 identity()square() .

然後它運行 if-else 塊,因為 squareIt = True ,該塊返回 square ;這是一個函數。

現在 squareNumber = square 相當於。

def squareNumber(number)
  sq = number**2
    return sq

因此,當調用 squareNumber(25) 它時,它返回了 625。

閉包是與內部函數和返回函數相關的重要概念。當嵌套/內部函數從其包含(封閉)函數的作用域引用變數時,即使封閉函數已完成執行,也會發生閉包。

比如之前的函數只能返回 identity 和 square,如果想添加額外的功能怎麼辦?修改一下函數。

def modifyNumber(power):
 def raisePower(number):
  return number ** power

 return raisePower

如果我們調用外部函數

identity = modifyNumber(1)

該函數將返回到另一個函數,即 raisePower .請記住,返回的是尚未執行的函數。為了執行它,必須調用它。

identity(10)
#10
identity(25)
#25

為什麼當調用 identity(10) 時返回 10。因已經看到設置 identity = modifyNumebr(1)power = 1 and 它的集合 identity = raisePower ,它等價於

def identity(number):
  return number ** power

但是raisePowe函數沒有名為 power 的變數。該變數 power 位於函數的作用域 modifyNumebr 內,該函數已完成執行。

現在調用 identity(10) 的時候,它將如何執行這一行代碼 return number ** power ,它如何獲取它的值 power = 1

在 Python 中,當外部函數完成執行並返回內部函數時,它會將內部函數與其封閉環境或閉包一起打包。這意味著函數對象保留其包含作用域中定義的所有變數和名稱的引用。這允許內部函數稍後訪問和使用這些變數,即使外部函數已完成其執行並且這些變數通常超出範圍。

這有點像父母給孩子留下遺產。即使父母可能已不復存在,孩子仍然可以訪問所有繼承的資產。

可以根據需要多次調用我們的外部函數。

squareNumber = modifyNumber(2)
cubeNumber =  modifyNumber(3)
rootNumber = modifyNumber(0.5)

可以隨心所欲地調用我們的內在功能。

squareNumber(10)
#100
squareNumber(5)
#25
cubeNumber(3)
#27
rootNumber(25)
#5.0
rootNumber(16)
#4.0

或者我們可以將這種內部功能與嵌套的俄羅斯娃娃進行比較。可以嵌套儘可能多的函數。

def eventPlanner(evenName):
  print(f'Welcome to {evenName}')
  listOfParticipant = []
 
  def register(name):
    listOfParticipant.append(name)
    print(listOfParticipant)
    
    listOfTask = []
    def addTask(task):
      listOfTask.append(task)
      print(listOfTask)
    
    return addTask
  return register

添加了三層功能,一個在另一個內部。這就像一個洋蔥,調用一個層會讓我們返回到另一個具有層的函數。

如果調用第一層,它將返回一個註冊函數。

fareRegistration = eventPlanner("1st School Fair")

#Welcome to 1st School Fair

現在可以調用第二層。它將列印已註冊人員的列表,並返回給我們一個任務功能。

enamTasks = fareRegistration("Enam")

# ['Enam']

似乎只有一名會員註冊了票價。讓再註冊一個。

kalamTasks = fareRegistration("Kalam")

#['Enam', 'Kalam']

這裡需要注意的一件事是,由於閉包,它為我們列印了兩個名稱,儘管外部函數完成了它的執行,但它提供了直接的內部函數,直到變數的最新狀態。

enamTasks("visit tea stall")
#['visit tea stall']

enamTasks("visit book stall")
#['visit tea stall', 'visit book stall']

enamTasks("attend Magic Show")
#['visit tea stall', 'visit book stall', 'attend Magic Show']

同樣,可以為同樣註冊了票價的 Kalam 先生添加任務。

kalamTasks("Perform Magic")
#['Perform Magic']

總之,這些是 Python 中強大的概念。例如,內部函數允許我們在另一個函數的主體中定義函數,從而提供了一種封裝相關功能並保持代碼模塊化和組織化的方法。內部函數可以訪問封閉函數的變數和參數,使它們能夠利用和操作其包含範圍內的數據。

從其他函數返回函數為我們的代碼增加了另一層靈活性。它允許我們創建高階函數,根據特定要求生成和自定義函數。這種能力使我們能夠編寫更通用和可重用的代碼,並促進函數式編程模式。

當內部函數保留對其封閉作用域的引用,捕獲必要的變數和名稱時,就會形成與返回函數密切相關的閉包。這種機制使內部函數能夠訪問和利用其包含環境的狀態,即使在封閉函數完成執行之後也是如此。閉包為函數提供持久性和上下文,允許它們保留特定於其創建點的數據和行為。

這些概念使我們能夠編寫模塊化、可重用和可定製的功能,從而增強代碼的可讀性、可維護性和效率。無論我們是將它們用於數據封裝、函數工廠、回調還是其他目的,理解和利用內部函數、返回函數和閉包都可以擴展我們的編程工具包,並使我們能夠為各種問題編寫優雅而有效的解決方案。

科技分類資訊推薦

從陪跑個體到企業培訓,我的IP陪跑之路,越走越寬了 - 天天要聞

從陪跑個體到企業培訓,我的IP陪跑之路,越走越寬了

大家好,我是Tina。來繼續通過文章,分享我的自媒體創業生涯。來說說最近在乾的事兒。一今天給江南布衣的全國經銷商做了小紅書的業務輔導培訓。很難想像6年的時間,我從一名職場人,慢慢成長為一個自媒體人,然後成為超級個體,到最後一步步做到可以給企
vivo Y300 GT續航超耐用:內置7620mAh電池 還有直驅供電 - 天天要聞

vivo Y300 GT續航超耐用:內置7620mAh電池 還有直驅供電

【TechWeb】去年底以來,vivo推出了vivo Y300系列的多款機型,其中vivo Y300 Pro首發搭載了年度最大的6500mAh超薄藍海電池,打破了藍海電池容量紀錄,也刷新了vivo電池容量新高。而在近期,該系列的又一款新機——vivo Y300 GT也得到官宣並開啟預約,將在5月9日也就是今天10:00正式開售。現在有最新消息,近日官方進一步
人才需求達百萬級!人工智慧如何催生職業新賽道 - 天天要聞

人才需求達百萬級!人工智慧如何催生職業新賽道

人工智慧的應用場景,正像星火燎原般迅速鋪展延伸到各行各業,一系列充滿科技張力和未來想像的新興職業也應運而生,成為年輕一代心馳神往的職業新選擇。在內蒙古包頭市包鋼白雲鄂博鐵礦,電鏟式挖掘機的巨型鏟斗,一次可以鏟起10立方米的礦石。然而這個「巨無霸」的駕駛室里,卻空無一人。操作這輛挖掘機的工人正坐在距離采...
即時零售,美團、京東、淘寶們的新戰場 - 天天要聞

即時零售,美團、京東、淘寶們的新戰場

當京東殺入到外賣市場的時候,很多人僅僅只是關注的是「京東開始做外賣」這個點,但卻並未真正了解「京東開始做外賣」背後延伸開來的新邏輯。 隨著淘寶的加入,特別是隨著越來越多的解讀開始出現,人們開始發現,京東做外賣,並不僅僅只是做外賣,而是為了在即時零售的新戰場上佔據一席之地。 於是,「即時零售」的概念,被...
潮聲丨今天的機器人賽場,或許正是未來社會的預演 - 天天要聞

潮聲丨今天的機器人賽場,或許正是未來社會的預演

潮新聞 執筆 薛文春北京「半馬」才結束,世界人形機器人運動會又來了!5月7日,北京宣布全球首個為人形機器人組織的綜合性競技賽事——世界人形機器人運動會,將於8月15日在國家體育場(鳥巢)和國家速滑館(冰絲帶)舉辦。不得不說,最近這段時間,人
聯想拯救者十年硬核進化,Y9000P 2025成六邊形性能戰神 - 天天要聞

聯想拯救者十年硬核進化,Y9000P 2025成六邊形性能戰神

5月8日,以「熱AI自發光」為主題的聯想天禧AI生態春季新品超能之夜在上海璀璨啟幕。發布會以一場充滿科技感與年輕活力的「熱AI時尚秀」,演繹了AI熱力和青春活力的雙向奔赴。聯想重磅發布了天禧和想幫幫兩款智能體,面向年輕客戶發布全場景AI終端,更為大學生群體發布了量身定製的「青春有AI」教育特惠計劃。聯想集團高級副...