有很多Python的lambda教程[1]。最近我偶然发现一个,真挺有用的。是Mike Driscoll在Mouse VS Python 博客上的关于lambda的讨论) 。
Mike的讨论非常好:清晰,直接,且含有实用的示例。它帮助我终于领会了lambda,并导致我写的另一篇lambda教程。 一个用来构造函数的工具 基本上,Python的lambda是用于构造函数(或更精确地说,函数对象)的工具。这意味着,Python有两个构造函数的工具:def和lambda。 下面是一个例子。您可以以正常的方式用def构造一个函数,就像这样:
或者你可以用lambda
下面是lambda的其他的一些有趣的例子:
lambda的好处在哪里? 已经困扰我有很长一段时间的一个问题是:lambda的好处在哪里?为什么我们需要lambda? 答案是: 我们并不需要lambda,我们不用它一样可以做所有的事情。但是… 在特定的情况下,很是方便 - 它让编写代码更容易一些,而且编写的代码更整洁。 什么样的情况? 好,其中一个情况是,我们需要一个简单的一次性功能:将被只使用一次函数。 通常,写函数有两个目的:(a)以减少代码重复(b)模块化代码。
但是,假设你需要创建一个函数,将只被使用一次 - 只从应用程序中的一个地方调用。好吧,首先,你不需要给函数的名称。它可以是“匿名的”。而且你可以把它定义在你想使用它的地方。这就是lambda是非常有用的时候。 但是,但是,但是…你会说。
创造一个短的匿名函数可能的原因是什么? 那么,考虑一下代码片段,使用lambda来定义一个Tkinter的GUI界面按钮的行为。 (这个例子是来自Mike的教程。)
这里要记住的一点是,tk.Button需要一个函数对象作为参数传递给该函数的参数。该函数对象将是它(按钮)点击按钮时调用的函数。基本上,该函数指定了点击该按钮时,GUI会做什么。 因此,我们必须通过函数参数传递一个函数对象到一个按钮。并注意 – 因为不同的按钮做不同的事情 - 我们需要为每个按钮对象提供不同的函数对象。每个函数将只使用一次。 所以,尽管我们可以这样写
这样写更容易(且更清楚)
当一个GUI程序有这样的代码,该按钮对象需要“call back”到被提供给作为其命令的函数对象。 因此,我们可以说,lambda的最常见的用途之一是在GUI框架,如Tkinter和wxPython中写“回调(callback)”,。 这一切似乎很简单。所以… 为什么lambda如此难以理解? 我能想到四个原因: 首先Lambda难以理解,因为:一个lambda只能用一个表达式:什么是表达式? 很多人想知道这个问题的答案。如果你在Google上搜索了一下,你会看到很多的帖子,“在Python中,表达式和语句之间的区别是什么?” 一个很好的答案是,表达式返回(或计算结果为)值,而语句则没有。不幸的是,在Python中表达式也可以是一个语句,这种情况很容易造成糊涂。 – 赋值语句就像 A = B = 0,Python支持链式赋值。 (Python不是C) 很多情况下在当人们问这个问题时,他们真正想知道的是:什么样的情况下可以放入lambda,什么情况下不可以? 而对于这个问题,我觉得遵循一些简单的规则就足够了。
利用这些规则意味着:
难以理解的第二个原因是:一个lambda只有一个表达式:为什么?为什么只有一个?为什么不能多表达式?为什么不能是语句? 对于一些开发人员来说,这个问题的意思是为什么Python的lambda语法如此怪异?对于其他人,尤其是那些有Lisp的背景的,这个问题是指为什么Python的lambda这么残废?为什么不像Lisp的lambda那么强大? 答案是很复杂,它涉及Python语法的“pythonicity”。lambda是一个相对较晚加入Python的。它加入的时候,Python语法已经固定下来了。在这种情况下,语法的lambda必须用“Pythonic”的方式硬塞进一个已经建立好的Python语法中。导致可以在lambda表达式上来完成一些事情有一定的局限性。 坦率地说,我仍然认为lambda语法看起来有点怪异。尽管那样,但是Guido解释了为什么lambda的语法是不会改变的。 Python不会成为Lisp。 难以理解的第三个原因是::lambda通常被描述为一种工具,用于创建函数,但lambda语句中不含有返回语句。 在某种意义上,return语句隐含在lambda中。lambda规范必须包含只有一个表达式,表达式必须返回一个值,由lambda创建一个匿名函数隐式地返回表达式的返回值。这非常有意义。 还是 - 我想缺乏一个明确的return语句使得很难理解lambda,或者至少很难迅速理解。 难以理解的第四个原因是在lambda教程中通常会用作为创建匿名函数来引入lambda,其实最常见的lambda用途是用于创建匿名过程。 在编程的上古时期,我们就将子程序区分为两种不同的形式:过程和函数。过程是用来做事情的,并没有返回任何东西。函数是用于计算和返回值。函数和过程之间的差异已经成为一些编程语言的一部分了。在Pascal,例如,程序和函数是不同的关键字。 在大多数现代语言中,语言的语法中不再区分过程和函数。 例如Python的函数,可以像过程,函数,或两者兼而有之。(不是完全理想的)结果是一个Python函数总是被称为“函数”,即使它是本质上充当过程。 虽然过程和函数之间的区别已经基本消失的语言结构中,当思考有关程序如何工作的时候我们仍然时常用它。例如,当我读一个程序的源代码,并看到一些函数F,我揣摩F是做什么的。我经常可以把它归类到一个过程或函数 - 我会对自己说“F的目的是做这个的”,或“F的目的是计算和返回等这个和这个的”。 所以现在我想我们可以明白为什么lambda的许多解释是难以理解。 First of all, the Python language itself masks the distinction between a function and a procedure. 首先,Python语言本身模糊了函数和过程的区别。 第二,大多数教程介绍把lambda作为创建匿名函数的工具来介绍,其主要目的是要计算并返回结果。在大多数教程看到(这个包含)的第一个例子展示了如何编写一个lambda来返回值,x的平方根。 但是,这不是lambda最常用的方式,不是当他们在Google上搜索“python lambda教程”的时候要找的。对于lambda最常见的用途是创建匿名的过程,在GUI回调中使用。在这些用例中,我们不关心什么lambda返回什么,我们关心它做了什么。 这就解释了为什么典型的Python程序员难以理解大多数的lambda说明。因为他尝试学习如何编写一些GUI框架的代码:Tkinter,wxPython。运行这些lambda,想理解他们。Google“python lambda教程”。他发现那些以例子开始的教程是完全不适合他。 所以,如果你是这样的程序员 - 本教程是给你写的。我希望它能帮助到你。对不起,我们在本教程的结尾看到了这点,而不是开头。我们希望有一天,有人会写一个lambda教程,而不是以这种方式开头
而以这样的句子开始:
所以你需要有它。另一个lambda教程。 |