惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
D
DataBreaches.Net
P
Proofpoint News Feed
V
Visual Studio Blog
J
Java Code Geeks
Recorded Future
Recorded Future
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Full Disclosure
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
C
Cybersecurity and Infrastructure Security Agency CISA
V
Vulnerabilities – Threatpost
罗磊的独立博客
Jina AI
Jina AI
博客园 - 【当耐特】
C
CERT Recently Published Vulnerability Notes
G
GRAHAM CLULEY
Y
Y Combinator Blog
L
LangChain Blog
L
LINUX DO - 热门话题
宝玉的分享
宝玉的分享
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Help Net Security
云风的 BLOG
云风的 BLOG
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园_首页
A
About on SuperTechFans
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Latest news
Latest news
T
Threatpost
T
Tenable Blog
有赞技术团队
有赞技术团队
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Stack Overflow Blog
Stack Overflow Blog
C
Cisco Blogs
C
Check Point Blog
T
Tor Project blog
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
美团技术团队
I
Intezer
S
Securelist
AWS News Blog
AWS News Blog

博客园 - FantasySoft

PHP菜鸟手记——如何解决无法装载动态链接库的问题 穿在身上的手机——M-Dress 团购之道——双赢才是核心 Demand Media——深谙中庸之道的新媒体 云中谁寄锦书来,盛大也! 《黑客》月刊中文版第一期正式发布,很给力!推荐围观! 比尔•盖茨:未来最好的教育来自互联网 CaptureDeviceManager.getDeviceList方法返回null对象问题探究 为了生活更美好,玩游戏吧! 三言两语话委托 IronPython Tools——为IronPython度身定做的IDE 从博客园口水仗想到的 由XML Literal引发的思考 作为.NET程序员,您需要IronPython么? 静态注册BroadcastReceiver的注销问题 大道至简——Michael看iPad 波哥大BRT带来的启示 Timberland的企业社会责任 比尔•盖茨谈教育
lambda与闭包
FantasySoft · 2010-05-03 · via 博客园 - FantasySoft

2010-05-03 16:43  FantasySoft  阅读(7368)  评论()    收藏  举报

《作为.NET程序员,您需要IronPython么?》一文中,Michael给大家介绍了IronPython的诸多优点,其中的一条就是IronPython实现闭包要比C#和VB.NET来得更为直观。在文中,针对“找出长度较短的字符串”的功能,我给出了IronPython的代码:

>>> SampleData = ["the""quick""brown""fox""jumped","over""the""lazy""dog"]
>>> maxLength = raw_input("Maximum length of string to include?"
>>> maxLength = int(maxLength)
>>> shortWords = [i for i in SampleData if len(i) <= maxLength]

这段代码的核心在于最后一个赋值语句,它是典型的列表内涵(List Comprehension)的应用。而事实上,这个赋值语句等价于以下的代码:

shortWords = filter(lambda i: len(i) <= maxLength, SampleData)

使用这样的代码也许和C#和Java的闭包-Jon谈《The Beauty of Closures》一文中C#代码具有更强的可比性,因为lambda是Python中用于定义匿名函数的关键字,而匿名函数又是实现闭包的充分条件之一(非必要条件)。在讨论闭包和lambda之前,我们先来了解一下filter函数。


filter(function, sequence)函数是Python的内建函数,我们无需引入任何的包(package)即可使用。它实现了将序列中某些符合条件的元素筛选出来的功能;它需要两个参数:第一个是函数,用于定义筛选条件;而另一个则是序列,作为被筛选的对象。Python Tutorial给出的示例代码可以帮助我们更好地理解filter这个函数。

现在,您对filter函数有一定的认识了吧?那么让我们再回到上述的赋值语句。lambda定义了一个匿名函数,它返回了一个布尔值:True或者False,而判断条件则是:参数的长度小于或者等于maxLenth。在这里,lambda充其量只是一个语法糖,让代码更加易读,并没有体现出它与闭包的关系。说到这里,您一定会问:到底什么是闭包呢?从定义上来说:闭包就是由函数与其相关的引用环境组合而成的实体。如果一门语言很好地支持闭包,那么它需要具备以下条件:
    • 函数是语言的一等公民,它不从属于其它任何对象,可以作为方法的返回值;
    • 函数可以嵌套定义;
    • 可以捕获引用环境,并把引用环境和函数代码组成一个可调用的实体;
    • 允许定义匿名函数。
 基于上述条件的第三点,我们可以将上述代码改写为如下形式:

>>> SampleData = ["the""quick""brown""fox""jumped","over""the""lazy""dog"]
>>> def filterFunc(maxLength): 
...     
return lambda i: len(i) <= maxLength
>>> maxLength = raw_input("Maximum length of string to include?"
>>> maxLength = int(maxLength)
>>> shortWords = filter(filterFunc(maxLength), SampleData)

我们回头对照一下上述的条件,filterFunc不正是闭包的最好体现么?也许您会觉得我有点画蛇添足,多此一举,但是,我们确实拥有了一个极具灵活性的可调用实体。如果要筛选出最大长度为4的单词,我们可以这么做:

fourLetter = filter(filterFunc(4), SampleData)

如果要筛选出最大长度为3的单词,我们又可以这么做:

threeLetter = filter(filterFunc(3), SampleData)

我们回想一下面向对象编程当中的函数,它的定义是固定的,不会在运行时发生变化。而闭包则不同,它会根据不同的引用环境发生变化,从而返回不同的函数实例。因此,我会把闭包等同于返回值是函数的函数,而lambda的存在可以让返回的函数定义得到简化。更多有关闭包的介绍,请参考园子里的季方亮同学的文章——《函数编程之闭包漫谈(Closure)》;有关lambda的介绍,则请参考CoderZh同学的文章——《Python天天美味(35) - 细品lambda》

最后,也许有朋友会问:我们为什么需要lambda和闭包呢?这是为了将side-effect降至最低,也就是将变量从我们代码当中剔除!我想您一定会对此很惊讶,但这是事实,最纯粹的函数式编程是只有定义的。基于此,最开始的代码还能演变成如下所示:

>>> SampleData = ["the""quick""brown""fox""jumped","over""the""lazy""dog"]
>>> raw_input("Maximum length of string to include?")
>>> print(filter(lambda i:len(i) <= int(_), SampleData))

对编程范式感兴趣的朋友,可以参考我的文章:《说的都是概念——有关编程范式》