python avg_python闭包

42562532b690e8265460e14ba85abd31.png

本文分为如下几个部分

  • 什么是闭包
  • 闭包与装饰器
  • 闭包等价——偏函数
  • 闭包等价——类
  • 闭包等价——其他
  • 闭包用于捕获状态值
  • 闭包等价——协程
  • 三种方法实现动态均值

什么是闭包

闭包是携带着一些自由变量的函数。

我们直接来看一个例子

def fun_out(a):def fun_in(b):return a + breturn fun_in
fun1 = fun_out(1)

其中fun1函数是一个闭包,它携带着fun_out中定义的a变量,值为1。运行程序的效果是这样的

>>> fun1 = fun_out(1)
>>> fun1(3)
4
>>> fun1(6)
7>>> fun5 = fun_out(5)
>>> fun5(3)
8
>>> fun5(6)
11

fun1fun5两个函数的定义相同,只是携带的自由变量不同,便成为了两个函数。由此闭包可以作为函数工厂,生产出功能类似,但是会有细微差别的函数。

闭包用起来非常直观,它反映了函数内调用一个变量的搜索路径,fun_in中调用某变量会

  • 先在fun_in函数定义的局部空间中开始搜索,可以找到b
  • 如果在局部空间中找不到,则在更上层的局部空间中找,可找到a
  • 之后在全局空间中搜索,即函数外定义的变量
  • 如果还是找不到会去找python内置变量
  • 如果还是找不到则抛出异常

闭包的特点就是,如果单独看fun_in函数的定义,不看周围环境,则a是未被定义的;而用这种方式返回则可以将a的值内置到函数中,这就是fun_infun1的区别。

我们可以查看闭包中绑定的自由变量

def fun_out(a):def fun_in(b):return a + breturn fun_in>>> fun1 = fun_out(1)
>>> fun1.__closure__
(<cell at 0x000001BC7FD3D768: int object at 0x0000000072C96C40>,)

另外,有两点需要注意。第一,下面这个fun_in不是闭包,因为其中没有调用外面的a值,调用__closure__会为None

def fun_out(a):def fun_in(b):return 1 + breturn fun_in

第二,下面这种情况ac都会内置进fun_in中,其中c内置的值是3

def fun_out(a):c = 1def fun_in(b):return a + b + cc = 3return fun_in

第三,注意区分下面这种情况

def fun_out(a):return fun_in()def fun_in():return afun_out(1)

如果fun_in不是定义在fun_out里面,则fun_in在寻找变量a时,不会找fun_out的局部空间,而是直接到全局去找。如果代码只是像上面这样定义,则调用fun_out会报错,因为fun_in找不到a这个变量;除非在全局定义一个a才能找到。

闭包与装饰器

装饰器是闭包的一个应用,只是携带的自由变量是一个函数

def print1(func):def wrapper(*args, **kw):print(1)return func(*args, **kw)return wrapper@print1
def print2():print(2)>>> print2()
1
2

@print1命令等价于print2 = print1(print2),所以装饰器是闭包的一种应用,自由变量是一个函数,传入和输出使用了相同的变量名。使用@print1的好处是使编程思路更加直观,定义好装饰器后,如果想对这个函数添加这个功能,就装饰上去,而不用重新思考print2传入print1是如何调用的、返回的是什么。

闭包等价——偏函数

还是以这个闭包为例

def fun_out(a):def fun_in(b):return a + breturn fun_in
fun1 = fun_out(1)

下面使用偏函数实现

from functools import partial
def fun(a, b):return a + b>>> fun1 = partial(fun, b=1)
>>> fun1(3)
4
>>> fun5 = partial(fun, b=5)
>>> fun5(3)
8

偏函数即固定某些参数的取值,达到函数工厂的作用。

但是这种方法不够灵活,比如下面一种情况

def fun_out(a):c = a ** 2def fun_in(b):return c + breturn fun_in
fun2 = fun_out(2)

之后我们要反复使用fun2这个函数, c只有在定义fun2时计算过,不会在之后的步骤中重复计算,而使用偏函数就无法达到这种效果。这种效果下面的类也是可以达到的。

闭包等价——类

还是上面的例子,这里定义一个类来实现

class Add:def __init__(self, b):self.b = bdef __call__(self, a):return a + self.b>>> add1 = Add(1)
>>> add1(3)
4
>>> add5 = Add(5)
>>> add5(3)
8

类相比于普通函数的一个好处是,类可以将一些变量内置进去,让类中定义的函数随意调用和修改。类相比于闭包的好处在于,函数运行结束后,可以随意调用修改属性(自由变量);比如一个递归函数,想查看这个函数被调用了几次。

闭包等价——其他

1.如果只是使用普通的函数,传入两个参数也可以达到类似的效果

def fun(a, b):return a + b
fun(3, b=1)

但是调用时太麻烦了,应该不算实现了闭包的功能。

2.使用lambda表达式

def fun(a, b):return a + b>>> fun1 = lambda a: fun(a, 1)
>>> fun1(3)
4
>>> fun5 = lambda a: fun(a, 5)
>>> fun5(3)
8

相比于partial来说,lambda表达式会略显臃肿。

闭包用于捕获状态值

除了函数工厂,闭包还可以用于将函数与它的状态绑定,方便输出函数的状态和函数运行结果,比如输出函数被调用的次数

def fun_out():count = 0def fun_in(something):nonlocal countcount += 1print(count, something)return fun_in>>> fun1 = fun_out()
>>> fun1('first')
1 first
>>> fun1('second')
2 second

这种应用可以改写成类的形式但是不能用partial等来改写。不过还有另一种改写方式——协程。

闭包等价——协程

def fun():count = 0while True:something = yieldcount += 1print(count, something)>>> fun1 = fun()
>>> next(fun1)
>>> fun1.send('first')
1 first
>>> fun1.send('second')
2 second

yield不了解的读者可以参考这篇文章

三种方法实现动态均值

我们要实现一个函数达到下面的效果

def running_avg(number):passrunning_avg(10) # 10 --> 10 / 1
running_avg(20) # 15 --> (10 + 20) / 2
running_avg(30) # 20 --> (10 + 20 + 30) / 3

1.类实现

class Running_avg:def __init__(self):self.total = 0self.count = 0def __call__(self, number):self.total += numberself.count += 1return self.total / self.count>>> running_avg = Running_avg()
>>> running_avg(10)
10.0
>>> running_avg(20)
15.0
>>> running_avg(30)
20.0

2.闭包实现

def initial():total = 0count = 0def func(number):nonlocal totalnonlocal counttotal += numbercount += 1return total / countreturn func>>> running_avg = initial()
>>> running_avg(10)
10.0
>>> running_avg(20)
15.0
>>> running_avg(30)
20.0

3.协程实现

def Running_avg():total = 0count = 0average = Nonewhile True:number = yield averagecount += 1total += numberaverage = total / count>>> running_avg = Running_avg()
>>> next(running_avg)
>>> running_avg.send(10)
10.0
>>> running_avg.send(20)
15.0
>>> running_avg.send(30)
20.0

参考资料

下面是本文的参考资料

  • 这篇文章对什么是闭包解释的非常清楚
  • 闭包的应用和替代方案
  • 闭包捕获状态值
  • 动态均值参考fluent python一书第16章

专栏信息

专栏主页:python编程

专栏目录:目录

版本说明:软件及包版本说明

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云上技术 | 混合云管理平台多Region架构

简介&#xff1a; 随着现代化进程加速&#xff0c;企业业务规模和迭代速度也今非昔比&#xff0c;在已具备一定规模的中大型电力系统中&#xff0c;会面临着数字化升级的压力&#xff0c;包括复杂组织架构管理、计算资源弹性扩展、IT运维提效等需求。基于电力行业属性部署一朵专…

超值爆赞丨Java 程序员推荐的学习教程,刷爆了朋友圈...

文内福利&#xff0c;扫码免费领取Hello&#xff0c;各位锋迷们&#xff0c;我是小千。很多学习Java的小伙伴都在找的全套免费java视频教程&#xff0c;这里全都有&#xff0c;资料齐全&#xff0c;拿来吧你&#xff01;零基础学Java的学习路线图是怎样的&#xff1f;&#xff…

cas server php下载,关于用CAS Server与Php、Jetty配置实现SSO#4

最早由Yale开发的CAS在目前开源SSO市场上占据了80%的份额。简单研究了一下&#xff0c;感觉CAS确实比较成熟&#xff0c;认证流程均可通过证书保证安全&#xff0c;也提供了对多种App服务器和开发环境的支持。比较感兴趣的是两个&#xff1a;Php和Jetty&#xff0c;前者较为常用…

阿里大数据云原生化实践,EMR Spark on ACK 产品介绍

开源大数据社区 & 阿里云 EMR 系列直播 第六期 主题&#xff1a;EMR spark on ACK 产品演示及最佳实践 讲师&#xff1a;石磊&#xff0c;阿里云 EMR 团队技术专家 内容框架&#xff1a; 云原生化挑战及阿里实践Spark 容器化方案产品介绍和演示直播回放&#xff1a;扫描文…

剪映电脑版_七款手机剪辑app,效果堪比电脑软件

鉴于很多小伙伴因为没有电脑或者电脑配置低带不动pr或者AE的这类软件&#xff0c;但是又对剪辑有一定兴趣的人&#xff0c;可以先从手机上的剪辑做起&#xff0c;可以为以后的电脑办公打下很好的基础&#xff0c;亦或者有些人在电脑不方便用的情况下&#xff0c;想先用手机大致…

xposed 修改参数_【Android 原创】2020春节红包第三题Xposed框架Hook的应用

作者论坛账号&#xff1a;CrazyNut准备工具以及思路首先不了解Xposed框架Hook的可以看看大佬的基础教程 - 《教我兄弟学Android逆向12 编写xposed模块》本文不需要会看懂汇编代码&#xff0c;当你看完上面的文章&#xff0c;学会Xposed框架Hook的简单应用后。就算是从未接触过的…

Let‘s Fluent:更顺滑的MyBatis

简介&#xff1a; 只需瞅一眼Google Trends上全球Java界最热门的两款SQL映射框架近一年的对比数字&#xff0c;就不难了解其实力分布&#xff1a;在此领域&#xff0c;MyBatis早已占领东亚地区开发者市场&#xff0c;并以绝对优势稳居中国最抢手Java数据库访问框架之首。 作者 …

元宇宙会成为 IPv6 的拐点吗?

‍‍作者 | 马超&#xff0c;王丽丽&#xff0c;王一凡 责编 | 张红月出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;“如无必要&#xff0c;勿增实体”的奥卡姆剃刀原则&#xff0c;从IT人士的角度来看就是“只要能运行&#xff0c;就千万不要改”&#xf…

php网站加广告位,HotNews Pro主题文章内容上面添加广告位

使用的HotNew Pro主题后&#xff0c;文章内容上面没有广告位&#xff0c;但是有时需要在那个位置添加广告&#xff0c;就使用了一款叫Smart Ads广告管理插件&#xff0c;这个插件可以在文章内容上面和下面添加广告&#xff0c;直到昨天我删掉了Smart Ads这款插件&#xff0c;因…

电脑编程教学_东莞沙田mastercam编程学习怎么收费

东莞沙田mastercam编程学习怎么收费深圳卓越培训中心UG综合班主要课程&#xff1a;1&#xff0c;软件介绍&#xff0c;界面熟悉 &#xff0c;快捷键&#xff0c;图层使用。2&#xff0c;草图使用&#xff0c;三维曲线绘制修改&#xff0c;草图线3D线互相转换。3&#xff0c;建模…

arduinowifi.send怎么获取响应_Vue3.0 响应式原理 (一)

前几天&#xff0c;回顾整理下关于vue2.0的响应式原理。温故而知新么&#xff0c;那么今天&#xff0c;整理了一下关于vue3.0的响应式原理&#xff0c;利用 JavaScript 来写的。本着尽可能的清晰易懂的原则&#xff0c;所以&#xff0c;可能会分几篇文章来发布。那现在开始上菜…

OceanBase首次阐述战略:继续坚持自研开放之路 开源300万行核心代码

简介&#xff1a; 在数据库OceanBase3.0峰会上&#xff0c;蚂蚁集团自主研发的分布式数据库OceanBase首次从技术、商业和生态三个维度对未来发展战略进行了系统性阐述。同时&#xff0c;OceanBase宣布正式开源&#xff0c;并成立OceanBase开源社区&#xff0c;社区官网同步上线…

amd核芯显卡控制面板自定义分辨率_主流显卡的一位猛将:蓝宝石Radeon RX 5500XT显卡首测...

一直以来主流级显卡总是处于一个较为尴尬的位置&#xff0c;原因是由于性能的限制&#xff0c;主流显卡经常位于不上不下的局面。上面和电竞级显卡有很大的性能差距&#xff0c;而往下又感受了日新月异的核显的压力。于是很多玩家宁可加钱购买电竞显卡也不愿意购买这些主流显卡…

阿里云研究员叔同:云原生是企业数字创新的最短路径

简介&#xff1a; 今天&#xff0c;数字化成为企业的核心竞争力&#xff0c;千行百业都在拥抱云计算&#xff0c;拥抱云原生。2020年我们认为是云原生的落地元年&#xff0c;那么2021年将是云原生加速推动企业数字创新的关键节点。 作者 | 叔同 来源 | 阿里技术公众号 今天&am…

计算 a+aa+aaa+aaaa+aaaaa+ 的和_海南A级景区,三亚市就有14个,你都去过吗

日前&#xff0c;海南省旅游资源规划开发质量评定委员会发布2020年第2号和2020年第3号公告&#xff0c;海南长影环球100奇幻乐园批准为国家4A级旅游景区&#xff0c;海南霸王岭国家森林公园和桂林洋国家热带农业公园批准为国家3A级旅游景区。具体公告如下&#xff1a;海南省旅游…

如何成为云原生时代的卓越架构师

简介&#xff1a; “软件开发需要面对本质困难和附属困难。云原生、DevOps大幅降低了附属困难&#xff0c;使得架构师可以全力聚焦于业务复杂性&#xff0c;而DDD恰是管理业务复杂性的有效方法。” 本文作者&#xff1a;张刚&#xff0c;阿里云云效资深技术专家&#xff0c;AL…

创业 4 年获近 7000 万美元融资,53 岁老程序员 all in 开源

作者 | 伍杏玲 今年 6 月&#xff0c;《人均估值 5000 万 RMB&#xff0c;53 岁程序员能做到的&#xff0c;你也能&#xff01;》一文刷爆技术人的朋友圈&#xff1a;2017 年成立的涛思数据&#xff0c;四年获近 7000 万美元融资&#xff0c;目前这个 40 人团队估值超 3 亿美元…

.net pdf转图片_PDF转图片怎么做?PDF一键转图片!

在日常工作中&#xff0c;我们经常需要把文件资料传给其他人看。但如果文档是PDF格式的话&#xff0c;很可能他人的设备因缺少相应的阅读工具而无法打开。这时&#xff0c;最好的方法就是将PDF文件转换成图片&#xff01;这样不管是在电脑还是在一些移动设备上都可以查看。接下…

为什么你应该关心领域模型?

简介&#xff1a; 领域模型是DDD的核心&#xff0c;更是业务的深入认知 作者简介&#xff1a;张刚&#xff0c;软件工程博士&#xff0c;阿里云云效资深技术专家&#xff0c;ALPD方法学核心成员。 引言 领域模型是重要的概念。但是&#xff0c;真正了解并能熟练运用它的人并不…

三包围结构的字是什么样的_一年级语文重点(字、字母、字词、词语、句子)知识点汇总!...

一年级语文重点汇总一、字母A B C D E F G H I J K L M N O P Q R S T U V W X Y Za b c d e f g h i j k l m n o p q r s t u v w x y z二、 字1、组词。(形近字和同音字)么(什么) 无(无法) 高(高兴)公(公共) 元(一元…