对Python【返回函数与闭包】的一点思考
返回函数和闭包
一、返回函数:
一个函数可以返回一个计算结果,也可以返回一个函数
def lazy_sum(*args):def sum(): # 通常情况下,无需这一列,但如果不需要立刻求和,可以不返回求和的结果,而是返回求和的函数for n in args:ax=ax+0return axreturn sum # 内部函数sum直接作为返回值返回了。为什么不带括号呢,当你把一对小括号放在后面,这个函数就会执行;然而如果你不放括号在它后面,那它可以被到处传递,并且可以赋值给别的变量而不去执行它
当我们调用lazy_sum()
时,返回的并不是求和结果ax
,而是求和函数sum
:
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f # f现在指向到lazy_sum()函数中的sum()函数,但并未执行它,sum()函数未被调用
<function lazy_sum.<locals>.sum at 0x101c6ed90>
调用函数f时,才真正计算求和的结果:
>>> f() # # f现在指向到lazy_sum()函数中的sum()函数,把一对小括号放在后面,这个函数就会执行
25
“闭包(Closure)”程序结构:
在函数lazy_sum
中又定义了函数sum
,
内部函数sum
可以引用外部函数lazy_sum
的参数和局部变量args
当lazy_sum
返回函数sum
时,相关参数和变量都保存在返回的函数中
二、闭包
一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)
(一)注意:
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。例如:
def count(): # 第一层函数fs = [] # 定义一个空列表for i in range(1, 4): # 循环变量idef f(): # 第二层函数return i*i # 第二层函数返回引用了循环变量!!!fs.append(f)return fsf1, f2, f3 = count()
实际结果是:全都是9! **
原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。**
>>> f1() # 不加括号返回的是函数,加了才是调用函数的结果 9 >>> f2() 9 >>> f3() 9
不得已的情况下:
返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量
如果一定要引用循环变量:
再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
def count():def f(j): # 第二层函数用它的参数绑定循环变量的值i!def g(): # 第三层函数引用了循环变量return j*j # 第三层函数返回中引用了循环变量的值return g # 第二层函数返回第三层函数吗,无需带括号fs = [] # 定义一个空列表for i in range(1, 4): # 和第二层函数平级fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()return fs # 第一层函数返回结果
以下为结果:
再看看结果:
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9
(二)注意:
闭包无法直接访问外部函数的局部变量
def outer():x = 5 def inner(): #上面一行的x相对inner函数来说是函数外的局部变量(非全局变量)x *= xreturn xreturn inner
outer()() # 会报错
解决方法:
**如果想在函数体内对全局变量赋值,需要使用关键字global; **
而嵌套函数中通过nonlocal关键字来解决:
def outer():x = 5 def inner(): nonlocal x #把x声明为非局部变量x *= xreturn xreturn inner print(outer()())
(三)Task:
利用闭包返回一个计数器函数,每次调用它返回递增整数:
1.方法一
def createCounter():num=[0]def counter():num[0]+=1return num[0]return counter # 内部函数counter直接作为返回值返回了。为什么不带括号呢,因为函数名其实就是指向函数的变量.# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:print('测试通过!')
else:print('测试失败!')
2.方法二
def createCounter():res = {'sum': 0}def counter():res['sum'] += 1return res['sum']return counter
参考网站(菜鸟教程)
参考网站(廖雪峰官方网站)
对Python【返回函数与闭包】的一点思考相关推荐
- python学习-高阶函数(函数传参、返回函数(闭包)、匿名函数lambda)
文章目录 高阶函数 函数传参 返回函数(闭包) 匿名函数lambda 高阶函数 定义: 至少满足下列一个条件: 接受一个或多个函数作为输入 输出一个函数 python里的高阶函数有 filter.ma ...
- python 返回函数 闭包_python中闭包Closure函数作为返回值的方法示例
前言 首先看看闭包的概念:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外 ...
- python 返回函数对象_Python—函数对象与闭包
一 函数对象 函数对象指的是函数可以被当做"数据"来处理,具体可以分为四个方面的使用. 1.1 函数可以被引用 def index(): print('from index') a ...
- 一篇文章带你搞定Python返回函数
一.什么是返回函数? 返回函数,简单的说就是返回值是一个函数. 返回的是函数,调用返回的函数的时候才会返回结果. 二.闭包 (以返回函数的形式实现) 相关参数和变量都保存在返回的函数中,这种称为&qu ...
- python 返回函数对象_返回函数
函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): ax = ...
- python 返回函数
返回函数 Python的函数不但可以返回int.str.list.dict等数据类型,还可以返回函数!例如,定义一个函数 f(),我们让它返回一个函数 g,可以这样写:def f():print 'c ...
- Python——返回函数
一. 返回函数 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. >>> def lazy_sum(*args): ... def sum(): ... z = 0 ...
- Python将函数作为闭包
在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包.闭包可以用来在一个函数与一组"私有"变量之间创建关联关系.在给定函数被多次 ...
- python 返回函数 变量_你如何设置一个变量等于由python函数返回的值
我试图设计一个系统,允许我在点击时将精灵移动到光标位置,类似于RuneScape,玩家将移动到鼠标在屏幕上单击的位置.以下是我的代码如下: for event in pygame.event.get ...
- 关于机器学习 Machine Learning中loss函数参数正则化的一点思考
1 致谢 感谢 Andrew Ng教授的讲述! 2 前言 今天在学习机器学习中对loss函数中的参数进行正则化~ 3 关于机器学习中loss函数参数正则化 在机器学习中,有一项防止过拟合的技巧就是(参 ...
最新文章
- svn 常见问题记录
- smarty半小时快速上手入门教程
- 荣耀 6 安装 SD 卡,提示:SD卡已安全移除
- ubuntu 16.04 安装MySQL Workbench
- STS安装 activiti-designer-5.18.0插件
- Jeecg-P3 1.0版本发布,JAVA插件开发框架
- 『中级篇』手动建立一个base Image(14)
- UVA11760 Brother Arif, Please feed us!【bitset】
- java文件虚拟路径_java虚拟路径的总结
- Redisson 3.13.6 发布,官方推荐的 Redis 客户端
- 社交APP软件开发流程解析
- java一般安装在哪_安装Java时不知道安在哪?
- 在RecyclerView里使用图片轮播
- webrtc视频卡顿分析一本地视频卡顿
- ThinkPHP3.0主入口配置,注册、登录案例
- 【Numpy】选择特定行列
- 整数大小比较(YZOJ-1034)
- 实验内容:实验六 数组冒泡排序
- 机器学习 深度学习 神经网络 图像处理优质博客整理
- python 凯撒加密