(小甲鱼python)函数笔记合集五 函数(V)总结 函数的闭包(工厂函数)

news/2023/6/7 1:35:16

一、基础复习

  1. 函数的基本用法 创建和调用函数 函数的形参与实参等等
  2. 函数的几种参数 位置参数、关键字参数、默认参数等
  3. 函数的收集参数*args **args 解包参数详解
  4. 函数中参数的作用域 局部作用域 全局作用域 global语句 嵌套函数 nonlocal语句等详解

二、函数的闭包(工厂函数)

1.不通过外层函数funA()访问内层函数funB()
函数进行嵌套,只能通过外层函数funA()访问内层函数funB()。
闭包也称为工厂函数。
例1和例2通过外层函数funA调用funB()

#例1:
>>> def myfunc():x=520print(x)>>> myfunc()
520
>>> print(x)
Traceback (most recent call last):File "<pyshell#5>", line 1, in <module>print(x)
NameError: name 'x' is not defined
>>> 
#例2:
>>> def funA():x=880def funB():print(x)funB()>>> funB()
Traceback (most recent call last):File "<pyshell#13>", line 1, in <module>funB()
NameError: name 'funB' is not defined
>>> 
>>> funA()
880
>>> 

不通过funA()函数调用funB(),通过另一种方法访问内层函数funB(),也就是闭包。具体看例3和例4的解释

#例3:
>>> def funA():x=880def funB():print(x)return funB    #将funB()作为返回值返回>>> funA()   #得到funB()函数的一个引用
<function funA.<locals>.funB at 0x00000208BE292488>
>>> funA()()  #通过funA()()访问到内层函数funB()
880
>>> funny=funA()   #调用funA()函数,结果返回给一个变量。
>>> funny()   # 
880

例4:
对于嵌套外层函数的作用域会通过某种形式保存下来,尽管这个函数已经调用完了,但外层作用域里面的变量是会保存下来的。
代码解释:
闭包会把你的参数保存下来,创建一个不完整的函数,也就是只有exp这个参数,后续根据刚刚说的调用了里面的参数也就是给了base参数形成完整的函数。
1.第一个return返回的是计算的结果,第二个return返回的是exp_of函数本身。
2.执行power函数,返回的是exp_of函数的引用,相当于返回了已经定义exp变量的第一个return。
3.那么square()就是一个函数,括号里写的就是base变量。
return的意义在于返回函数的结果。

>>> def power(exp):def exp_of(base):return base ** exp    # base的exp次方return exp_of>>> square=power(2)   #square指向了exp_of函数,exp的值是2。
>>> cube=power(3)
>>> square(2)   # 2的2次方
4
>>> square(5)  #5的平方
25 
>>> power(2)(5)   # 另一种表达,第一次square=power(2),第二次调用square(5)相当于power(2)(5)
25
>>> 

例5:
代码解释:nonlocal关键字,会把内层函数x,y的结果赋值到x,y,所以每调用一次内层函数,都重新给外层赋值一次

>>> def outer():x=0y=0def inner(x1,y1):nonlocal x,yx+=x1y+=y1print(f"现在,x={x},y={y}")return inner>>> move=outer()
>>> move(1,2)
现在,x=1,y=2
>>> move(-2,2)
现在,x=-1,y=4

课后题:
1.为什么将闭包称之为 “工厂函数”?
答:顾名思义,工厂函数就是能产生函数的函数。
解析:

>>> def power(exp):
...     def exp_of(base):
...         return base ** exp
...     return exp_of
... 
>>> square = power(2)
>>> cube = power(3)
>>> square(5)
25
>>> cube(5)
125

上面代码中,power() 函数就是一个工厂函数,根据其参数的不同,得到了两个不同的“生产线”函数,一个是 square(),一个是 cube(),前者是返回参数的平方,后者是返回参数的立方。
2.实现闭包必须要用到嵌套函数吗?
答:是的,必须的。
解析:
在本质上,闭包就是将函数内部和函数外部连接起来的桥梁。
对于嵌套函数来说,外层函数的作用域是会通过某种形式保存下来的,内层函数可以在外层函数调用周期结束后,仍旧能访问到外层函数的变量(及参数)。
3.请问下面代码会打印什么呢?

>>> def funA():
...     x = 520
...     def funB():
...         print(x)
...     return funB
...
>>> funny = funA()
>>> del funA
>>> funny()
>>> # 请问这里会打印什么内容?

答:520。
解析:
del 语句这里会删除 funA() 函数吗?
答案是“会删,但又不会完全被删”!一个对象是否会被删除,取决于它是否还有人记得(引用)它。funA() 函数这里确实是已经被删除了,但它的内部有一个 funB() 函数仍然被 funny 引用着。换言之,当 return funB 语句被执行之后,funA() 函数的“影子”就残留在内存中了。哪怕 funA() 函数被删除了,它的“影子”也会一直在,只有当引用 funB() 函数的 funny 被删除,“影子”才会被随之抹去。
4.请问下面代码执行后,x 变量的值分别是多少?

def outter():def innerA():x = 100def innerB():nonlocal xx = 250def innerC():global xx = 520x = 880innerA()print(f"调用完 innerA() 函数之后,x = {x}")innerB()print(f"调用完 innerB() 函数之后,x = {x}")innerC()print(f"调用完 innerC() 函数之后,x = {x}")outter()
print(f"此时此刻,全局变量 x = {x}")

答:

调用完 innerA() 函数之后,x = 880
调用完 innerB() 函数之后,x = 250
调用完 innerC() 函数之后,x = 250
此时此刻,全局变量 x = 520

解析:
这里需要注意的是LEGB 规则以及 nonlocal 和 global 语法。
这里要注意的关键是 x = 880 是定义在 outter() 函数中的局部变量。但相对于 innerA()、innerB() 和 innerC() 这三个函数来说,它又是处于 LEGB 中的 E(嵌套函数的外层函数作用域),使用 nonlocal x 可以修改它的值。global x 修改的是全局变量的 x(注意:如果不存在,就会创建一个)。
5.如果想要函数 funA() 的调用结果如下,它的函数体应该如何定义?

>>> # 请定义 funA() 函数,使其调用结果如下。
>>> funA(3)(4)(5)
60

答:

>>> def funA(x):
...     def funB(y):
...         def funC(z):
...             return x * y * z
...         return funC
...     return funB
...
>>> funA(3)(4)(5)
60

6.挑战一下自己,请将下面这个闭包函数转换为 lambda 表达式的形式?

>>> def maker(n):
...     def action(x):
...         return x ** n
...     return action
>>> f = maker(2)
>>> f(3)
9
>>> f(5)
25

答:

>>> f = lambda n : lambda x : x ** n
>>> g = f(2)
>>> g(3)
9
>>> g(5)
25

题目来自小甲鱼函数(V)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4571584.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

菜鸟git学习记录

虽然工作中有用过git和gerrit gitWeb&#xff0c;但感觉还是不够了解git这个工具&#xff0c;到菜鸟网站配合公司内部一些学习资料重新学习一下。 Ubuntu18.0 中文配置 git安装&#xff1a;sudo apt-get 命令 当初也是一条安装命令解决。 配置全局用户名和邮箱&#xff…

APY超10000%+ SwapX Staking头矿真香

据SwapX中文社区消息&#xff1a;9月19日20:00&#xff0c;SwapX将正式开启LP Tokens质押挖矿&#xff0c;用户可质押SushiSwap、Uniswap、SwapX的流动性参与Staking&#xff0c;头矿预期APY&#xff08;年化收益率&#xff09;超10000% 。 截止此时&#xff0c;WBTC-ETH UNI-…

En-Tan-Mo隆重亮相Staking 生态大会

7月10日&#xff0c;由星球日报、区块律动联合主办的Staking 生态大会在北京召开。En-Tan-Mo创始人Aaron Yuan作为受邀嘉宾&#xff0c;与 Algorand、Cardano、Tezos、Dash、NEM等知名PoS 项目的创始人、负责人一道亮相此次活动。 会上&#xff0c;Aaron Yuan参加了以《Staking…

TokenInsight Staking Service 正式成为 CPChain 行业节点

近日&#xff0c;全球区块链项目评级机构TokenInsight旗下Staking业务品牌TISS&#xff08;TokenInsight Staking Service&#xff09;与CPChain达成战略合作&#xff0c;正式成为CPChain行业节点&#xff0c;将在链上数据、社区治理等方面为CPChain贡献力量。同时&#xff0c;…

科普 | ETH2 Staking 指南 :客户端多样性为何如此重要

作者 | Carl Beekhuizen翻译&校对 | 闵敏 & 阿剑来源 | 以太坊爱好者免责声明&#xff1a;本文没有贬低任何一个客户端。每个客户端&#xff0c;甚至是规范&#xff0c;可能都存在不足和漏洞。ETH 2.0 是一个复杂的协议&#xff0c;实现这个协议的人也都是肉体凡胎。本…

权益质押(Staking):这是关于什么的?

我们最近发表了三篇讲述Fetch.AI分类帐本的文章。这些概述&#xff1a; 我们的权益质押计划的主要特点和验证器的作用 影响我们设计权益质押模型设计的因素 我们的创新共识协议将如何改变用户体验 这些文章包含大量的信息&#xff0c;并回答了社区可能对该主题提出的许多问…

Stader Labs 通过战略销售筹集了 1200 万美元,因为它建立了“Staking as a Service”业务

加密股权平台 Stader Labs 周四宣布&#xff0c;它已经完成了由三箭资本牵头的 1250 万美元的私募交易&#xff0c;这家总部位于印度班加罗尔的公司估值为 4.5 亿美元。 Blockchain.com、Accomplice、GoldenTree Asset Management、Accel 等投资者也提供了资金。 Staking 是权…

最高年化收益36.5%!TOP Staking已开启“躺赚”模式

随着PoS&#xff08;包括泛PoS&#xff09;共识机制的越来越普遍&#xff0c;除了可以用矿机在区块链世界进行挖矿&#xff0c;还可以通过抵押代币的方式获得挖矿收益。这种被称为Staking的挖矿方式从2019年开始备受追捧&#xff0c;甚至催生了所谓的Staking经济。 TOP公链在主…