一文掌握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 中强大的概念。例如,内部函数允许我们在另一个函数的主体中定义函数,从而提供了一种封装相关功能并保持代码模块化和组织化的方法。内部函数可以访问封闭函数的变量和参数,使它们能够利用和操作其包含范围内的数据。

从其他函数返回函数为我们的代码增加了另一层灵活性。它允许我们创建高阶函数,根据特定要求生成和自定义函数。这种能力使我们能够编写更通用和可重用的代码,并促进函数式编程模式。

当内部函数保留对其封闭作用域的引用,捕获必要的变量和名称时,就会形成与返回函数密切相关的闭包。这种机制使内部函数能够访问和利用其包含环境的状态,即使在封闭函数完成执行之后也是如此。闭包为函数提供持久性和上下文,允许它们保留特定于其创建点的数据和行为。

这些概念使我们能够编写模块化、可重用和可定制的功能,从而增强代码的可读性、可维护性和效率。无论我们是将它们用于数据封装、函数工厂、回调还是其他目的,理解和利用内部函数、返回函数和闭包都可以扩展我们的编程工具包,并使我们能够为各种问题编写优雅而有效的解决方案。

科技分类资讯推荐

无人机不能无人管 - 天天要闻

无人机不能无人管

坚持统筹监管、系统防治,通过以规则规范行为、以技术驯服技术,无人机乱象才能得到有效根治。 图片内容来源于网络 彩云网评特约评论员 何冠军 近日,一段“穿越机在大理崇圣寺三塔的古塔券洞内飞行时坠落”的视频在网络流传,引发广泛关注。经查,涉事“飞手”张某某系擅自飞入三塔景区,大理市公安局依法对其处以行政拘留...
老有所“美”,乐龄群体乐享“数字人生” - 天天要闻

老有所“美”,乐龄群体乐享“数字人生”

“以前只会用手机按着说话,现在进步很大,学会做小视频、刷小红书,有疑问还会找AI帮忙。比如做扭扭棒手工花,我去社交平台找教程,处理老照片也尝试用美图功能。”76岁独居老人冯宣英阿姨,没想到晚年生活还能“美”出新高度。
智数科技集团拟折让约18.39%配售最多1970万股 净筹约680万港元 - 天天要闻

智数科技集团拟折让约18.39%配售最多1970万股 净筹约680万港元

智通财经APP讯,智数科技集团(01159)发布公告,于2025年5月9日(交易时段后),公司与配售代理订立配售协议,据此,公司委任配售代理(作为公司的独家代理)尽最大努力于配售事项的先决条件获达成后,按每股配售股份0.355港元的价格配售最多1970万股配售股份予不少于六名承配人。配售价较于配售协议日期联交所所报收市价每股股...
“张湾智警”上岗!无人机变身 “空中 110” - 天天要闻

“张湾智警”上岗!无人机变身 “空中 110”

晨曦中,数公里外的路口突发拥堵,一架印有“张湾智警”标识的无人机从机库起飞,通过空中喊话疏导车流,同时将车牌识别画面,实时推送至地面执法终端。这一幕高效协同的智慧警务场景,正是“张湾智警”无人机系统融入城市治理的日常缩影。
联想憋了40年的大招:自研5nm芯片上市,这次真没放鸽子 - 天天要闻

联想憋了40年的大招:自研5nm芯片上市,这次真没放鸽子

最近科技圈最热闹的事,莫过于联想在自家新平板上塞了颗"中国芯"。这事要搁五年前,网友能把键盘敲出火星子——毕竟在很多人印象里,联想除了组装电脑就是卖手机,突然掏出颗5纳米芯片,比四川变脸还让人意外。说起联想和芯片的恩怨情仇,那真是三天三夜唠
国产手机冲高端:别光顾着堆料,先学会把价格打上去 - 天天要闻

国产手机冲高端:别光顾着堆料,先学会把价格打上去

最近翻看Counterpoint的2025年一季度手机市场报告,有个数据看得人直嘬牙花子:苹果手机的平均售价还是816美元,相当于5800多块人民币,而小米的均价才155美元,折合人民币1100出头。这价格差得,都能买五台小米凑个"五福临门
moto razr 60系列三款新机发布,3499元起售 - 天天要闻

moto razr 60系列三款新机发布,3499元起售

继此前moto方面确认,新款小折叠razr 60系列即将5月8日在国内市场正式发布后,陆续在预热活动中公布的产品端相关信息也吸引了众多消费者的关注。昨日官方正式发布了razr 60系列三款机型,其中包含一款被命名为razr 60 Pro的新机,该系列机型的售价则从3499元起跳,参与国补后最低仅需2999元。外观方面,razr 60系列三款机型...