深入理解python特性_深入理解Python特性(2)

前面介绍了函数可以包含内部函数,甚至可以从父函数返回内部函数。现在做好准备,下面将进入函数式编程中较深的领域。内部函数不仅可以从父函数返回,还可以捕获并携带父函数的某些状态。下面对前面的get_speak_func示例做些小改动来逐步说明这一点:

d520026895515eeaa5d1a2863cd280b4.png

仔细看看内部函数whisper和yell,注意其中并没有text参数。但不知何故,内部函数仍然可以访问在父函数中定义的text参数。它们似乎捕捉并记住了这个参数的值。拥有这种行为的函数被称为词法闭包(lexical closure),简称闭包。闭包在程序流不在闭包范围内的情况下,也能记住封闭作用域中的值。实际上,这意味着函数不仅可以返回行为,还可以预先配置这些行为。用另一个例子来演示一下: 

83639cfe6d5df0d04f42e77f3436816e.png

这个例子中,make_adder作为工厂函数来创建和配置各种adder函数。注意,这些adder函数仍然可以访问make_adder函数中位于封闭作用域中的参数n。虽然Python中所有函数都是对象,但反之不成立。有些对象不是函数,但仍然可以调用,因此在许多情况下可以将其当作函数来对待。如果一个对象是可调用的,意味着可以使用圆括号函数调用语法,甚至可以传入调用参数。这些都由__call__方法完成:

ae88d93d88ef5e5db1f21b60c4b70ddd.png

当然,不是所有对象都可以调用,Python内置了callable函数,用于检查一个对象是否可以调用。

6543ddf3dc5c09180bd48820c1e0bb31.png

lambda是单表达式函数Python中的lambda关键字可用来快速声明小型匿名函数。lambda函数的行为与使用def关键字声明的常规函数一样,可以用于所有需要函数对象的地方。

d4037d319d5567e3b02da7033fe36307.png

lambda函数只能含有一个表达式,不能使用语句或注解,不能使用返回语句。执行lambda函数时会计算其中的表达式,然后自动返回表达式的结果,所以其中总是有一个隐式的返回表达式。应该在什么时候使用lambda函数呢?从技术上讲,每当需要提供一个函数对象时,就可以使用lambda表达式。而且lambda是匿名的,不需要分配名字。因此,lambda能方便灵活的快速定义Python函数。

9383d948d0bfb0b22a31b16af5f76057.png

上面的例子按照每个元组中的第2个值对元组列表进行排序。这种情况下,用lambda函数能快速修改排序顺序。下面是另一个示例:

dc653492e3602af57df4ceab01ff8818.png

希望你能从中看出lambda带来的灵活性。lambda也可以像词法闭包那样工作。词法闭包是什么?这只是对某种函数的一个奇特称呼,该函数能记住来自封闭词法作用域的值,即使程序流已经不在作用域中也不例外。

fe13762c695d9076b4e7b1fa28562596.png

在上面的例子中,即使是在make_adder函数(封闭的作用域)中定义的,但对于x + n  ,lambda仍然可以访问n的值。  不应过度使用lambda

c78a4c2dd6f3bd086828b2f0afe052a2.png

以上这种方式虽然在技术上可行且足够花哨,但会让那些工期很紧并且需要快速修复bug的人觉得难以理解。将lambda和map()或filter()结合起来构建复杂的表达式也很难让人理解,此时用列表解析式或生成器表达式通常会清晰不少:

118604d642fb31096d695ec0b954fb99.png

今天就到这,下一节我会介绍Python中非常重要的特性:装饰器!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值