快捷搜索:  汽车  科技

python中的lambda函数用法:Python函数Lambda闭包

python中的lambda函数用法:Python函数Lambda闭包我们使用lambda关键字声明一个lambda函数。 在此关键字之后,我们指定参数列表,其数量可以从零到多个变化。 然后,我们指定要执行的操作,称为lambda函数的表达式。lambda arguments: expression在上面的代码中,我们使用def关键字声明了一个名为add_up的函数。 此函数将两个数字(num1和num2)作为输入参数,计算它们的总和作为已定义的运算,然后将此值作为函数的输出返回。 很简单吧?除了这些常规函数外,Python中还有其他种类的函数可以使我们的开发受益。 让我们在本文中对其进行回顾。Lambda函数是小的匿名单行函数。 有时,我们可以简单地将它们称为lambda。 Lambda具有以下语法:

了解Python中的四个高级函数概念

python中的lambda函数用法:Python函数Lambda闭包(1)

> Photo by Tim Swaan on Unsplash.

Python函数是一段代码,可在需要运行时执行特定的操作,我们称其为函数。 大多数时候,我们使用以下语法声明并调用函数:

在上面的代码中,我们使用def关键字声明了一个名为add_up的函数。 此函数将两个数字(num1和num2)作为输入参数,计算它们的总和作为已定义的运算,然后将此值作为函数的输出返回。 很简单吧?

除了这些常规函数外,Python中还有其他种类的函数可以使我们的开发受益。 让我们在本文中对其进行回顾。

Lambda函数

Lambda函数是小的匿名单行函数。 有时,我们可以简单地将它们称为lambda。 Lambda具有以下语法:

lambda arguments: expression

我们使用lambda关键字声明一个lambda函数。 在此关键字之后,我们指定参数列表,其数量可以从零到多个变化。 然后,我们指定要执行的操作,称为lambda函数的表达式。

如您所见,lambda具有非常简洁的语法,因此它们最适合需要简短的一次性使用功能的场景。 让我们考虑以下示例。 sorted()函数用于根据key参数指定的key函数对可迭代对象进行排序:

>>> # define a list of tuples >>> records = [(1 'John') (2 'Aaron') (5 'Ian')] >>> # sort with a lambda >>> sorted(records key=lambda x: len(x[1]))[(5 'Ian') (1 'John') (2 'Aaron')]

在上面的代码中,我们首先定义一个列表来存储一些学生及其学生ID和姓名的记录。 然后,我们使用lambda函数对它们进行排序,该函数按学生姓名的长度对列表进行排序。

有关使用lambda函数进行排序的信息,请参阅我的上一篇文章。 同样重要的是要知道可能会滥用lambda。 为了方便起见,提供了以下文章:

闭包

闭包是嵌套函数,可捕获外部函数的非局部变量。 我认为从概念上理解闭包并不容易。 透彻的理解需要深入了解范围和函数(它们是Python中的一流对象)。 出于本文的目的,让我们通过看一个具体的示例来总体了解闭包:

>>> # create a closure >>> def make_multiplier(coefficient): ... product = 1 ... ... def multiplier(): ... nonlocal product ... product *= coefficient ... return product ... ... return multiplier ...

在上面的代码中,我们定义了一个名为make_multiplier的函数。 因为它包含另一个函数乘法器,所以我们可以将make_multiplier称为外部函数,并将multiplier称为嵌套函数。 外部函数返回嵌套函数作为其返回值。 重要的是,嵌套函数使用并修改在外部函数范围内定义的非局部变量(即乘积)。 综上所述,在Python中创建闭包包含三个关键要素:

· 在外部函数的范围内声明一个嵌套函数。

· 嵌套函数范围之外的非局部变量的绑定。

· 返回嵌套函数以输出闭包函数。

我们如何使用闭包? 让我们看下面的简单例子:

>>> multipler3 = make_multiplier(3) >>> multipler3() 3 >>> multipler3() 9 >>> multipler3() 27 >>> multipler3.__code__.co_freevars ('coefficient' 'product') >>> multipler3.__closure__[1].cell_contents 27

然后,我们声明一个名为multiplier3的闭包。 每次我们称此闭包为乘积乘以3。 换句话说,封盖"记住"产品最后一次使用后的状态。 相关概念包括变量绑定和值捕获。 我们可以通过调用__code __。co_freevars和__closure __ [1] .cell_contents来检查相关信息。

装饰器

装饰器是可扩展其他功能的行为而无需显式修改它们的功能。 本质上,装饰器是一种高阶函数,定义为将其他函数作为输入或将其他函数作为输出返回的函数。 通过下面的示例,让我们真正了解装饰者:

>>> def clap(): ... print("Clap! Clap!") ... >>> # define a higher order function >>> def triple_repeat_wrapper(func): ... def wrapper(): ... print(f"Before calling func {func.__name__}") ... func() ... func() ... func() ... print(f"After calling func {func.__name__}") ... return wrapper ...

在上面的代码中,我们定义了两个函数(clap和Triple_repeat_wrapper),后者是一个高阶函数,该函数在嵌套包装函数中调用传递的func三次,然后将包装函数作为高阶函数的输出返回。

我们如何使用这些功能? 如下代码所示,我们创建了一个称为wrapd_clap的函数,该函数将拍手函数传递给高阶函数Triple_repeat_wrapper。 如您所见,调用wrapped_clap函数将导致嵌套包装器函数内部的代码被调用。 与打印输出一致,我们知道wrapped_clap函数引用了嵌套函数包装器。

>>> wrapped_clap = triple_repeat_wrapper(clap) >>> wrapped_clap() Before calling func clap Clap! Clap! Clap! Clap! Clap! Clap! After calling func clap >>> wrapped_clap <function triple_repeat_wrapper.<locals>.wrapper at 0x1038f0680>

但是,回想一下,当您看到一些有关装饰器的示例代码时,您肯定已经看到了@符号的用法。 这个符号如何与我们上面定义的功能一起发挥作用? 让我们通过参考以下代码来解决这个问题:

>>> @triple_repeat_wrapper ... def hooray(): ... print("Hooray! Hooray!") ... >>> hooray() Before calling func hooray Hooray! Hooray! Hooray! Hooray! Hooray! Hooray! After calling func hooray >>> hooray <function triple_repeat_wrapper.<locals>.wrapper at 0x1038f0830>

在上面的代码中,我们声明了一个名为hooray的函数。 当我们调用此函数时,输出的格式与前一个wrapd_clap函数的输出相同。 同样,hooray函数引用嵌套包装器函数。

为什么会这样? 您可能已经注意到,在此hooray函数的声明上方,我们在Triple_repeat_wrapper函数名称之前使用@符号。 这只是装饰者的语法糖。 本质上,我们告诉Python解释器,我们将要定义的函数将由decorator函数包装。

Curry

以数学家Haskell Curry的名字命名的currying是指通过应用部分参数从现有函数创建新函数。 因此,该概念有时也称为部分功能。

与上述概念相比,这一概念更容易理解。 让我们考虑下面的简化示例,使用与上面定义的相同的add_up函数:

>>> # define a function returns a value >>> def add_up(num1 num2): ... sum_n = num1 num2 ... return sum_n ... >>> # define a partial function that adds seven >>> add_seven = lambda x: add_up(7 x) >>> add_seven(10) 17 >>> add_seven(72) 79 >>> # use a regular def keyword >>> def add_eight(x): ... return add_up(8 x) ... >>> add_eight(10) 18

在上面的代码中,我们使用lambda函数将数字7设置为add_up函数的第一个参数。 换句话说,创建的add_seven函数是原始add_up的部分函数,第一个参数始终设置为7。除了使用lambda函数之外,使用常规方法通过def关键字定义函数当然是可以接受的。

functools模块中提供了另一个方便的用于创建部分功能的工具。 考虑以下示例。 我们使用partial函数创建add_ten函数,该函数的默认参数为10,该函数调用add_up函数:

总结

在本文中,我们回顾了Python函数基础之外的四个高级概念。 以下是这些概念的简要概述:

· Lambda是匿名函数,在需要简单的一次性内联函数的情况下非常方便。

· 闭包是嵌套函数,它们绑定周围范围的非局部变量。

· 装饰器是可修改其他功能的行为的高阶功能。

· Currying是我们通过设置一些默认参数从现有函数中创建部分函数的方法。

(本文翻译自Yong Cui Ph.D.的文章《Python Functions: Lambdas Closures Decorators and Currying》,参考:https://medium.com/better-programming/python-functions-lambdas-closures-decorators-and-currying-83165d099abe)

猜您喜欢: