class参数传⼊python_在Python中将函数作为参数传⼊另⼀个
函数中
在我们的Python学习中,我们学到的众多令⼈瞠⽬结⾆的事实之⼀是,你可以将函数传⼊其他函数。你可以来回传递函数,因为在Python
中,函数是对象。
在使⽤Python的第⼀周,你可能不需要了解这些,但是随着你对Python的深⼊研究,你会发现理解如何将⼀个函数传⼊另⼀个函数是⾮常
⽅便的。
这是我关于“函数对象”的各种属性的系列⽂章的第1部分。本⽂主要关注⼀个新的Python程序员应该了解和欣赏的关于Python函数的对
象本质的内容。
函数可以被引⽤
如果你试图使⽤⼀个函数⽽不在它的后⾯加上圆括号,Python不会报错,但它也不会做任何有⽤的事情:
这也适⽤于⽅法(⽅法是存在于对象上的函数):
Python允许我们引⽤这些函数对象,就像我们引⽤⼀个字符串、⼀个数字或⼀个range对象⼀样:
由于我们可以像引⽤其他对象⼀样引⽤函数,所以我们可以将⼀个变量指向⼀个函数:
这个gimme变量现在指向我们的number列表上的pop⽅法。因此,如果我们调⽤gimme,它会做与调⽤相同的事情:
注意,我们并没有创建⼀个新函数。我们只是将gimme变量名指向了函数:
你甚⾄可以将函数存储在数据结构中,然后再引⽤它们:
获取⼀个函数并给它另⼀个名称或将它存储在⼀个数据结构中这样的操作并不常见,但是Python允许我们这样做,因为函数可以像任何其
他对象⼀样被来回传递。
函数可以被传⼊其他函数中
与任何其他对象⼀样,函数可以被作为参数传给另外的函数。
例如,我们可以定义⼀个函数:
然后,我们将它传⼊内置的help函数来看看它的功能:
我们也可以将这个函数传⼊它⾃⾝(是的,这很奇怪),这⾥,它⾃⾝会将这个函数转换为⼀个字符串:
实际上Python中有相当多的内置函数是专门⽤来接受其他函数作为参数的。
内置的filter函数接受两个参数:⼀个function和⼀个iterable。
这个给定的iterable(列表、元组、字符串等)会被循环,⽽这个给定的function会在该iterable中的每个项⽬上被调⽤:每当这个function返
回True(或另外的真值)时,该项⽬就被包含在filter输出中。
因此,如果我们给filter传⼊⼀个is_odd函数(当给定奇数时,它会返回True)和⼀个数字列表,我们将得到我们给它的所有数字中是奇数的
数字。
从filter返回的对象是⼀个延迟迭代器,因此我们需要将其转换为⼀个list,以实际查看其输出。
由于函数可以被传⼊函数,这也意味着函数可以接受另⼀个函数作为参数。filter函数假设它的第⼀个参数是⼀个函数。你可以认为filter函
数和这个函数差不多⼀样:
这个函数要求predicate参数是⼀个函数(技术上来说它可以是任何可调⽤对象)。当我们调⽤该函数(使⽤predicate(item))时,我们向它传
递⼀个参数,然后检查其返回值的真假。
lambda函数就是这样⼀个例⼦
lambda表达式是Python中⽤于创建匿名函数的⼀种特殊语法。当你对⼀个lambda表达式进⾏计算时,你得到的对象被称为lambda函数。
lambda函数与普通的Python函数⾮常相似,但有⼏点需要注意。
与其他函数不同,lambda函数没有名称(它们的名称以显⽰)。它们也不能有⽂档字符串,并且只能包含⼀个Python表达式。
你可以将lambda表达式看作是创建⼀个函数的快捷⽅式,该函数将对单个Python表达式进⾏计算并返回该表达式的结果。
因此,定义⼀个lambda表达式实际上并不会计算该表达式的值:它返回⼀个可以稍后计算该表达式的函数。
我想指出的是,以上三个lambda例⼦都是不好的例⼦。如果你想要⼀个变量名指向⼀个你可以稍后使⽤的函数对象,那么你应该使⽤def来
定义⼀个函数:这是定义函数的通常⽅法。
lambda表达式是⽤来定义⼀个函数并⽴即将其传递给另⼀个函数的。
例如,这⾥我们使⽤filter来获得偶数,但我们使⽤了⼀个lambda表达式,所以我们不必在使⽤它之前定义⼀个is_even函数:
这是lambda表达式最合适的⽤法:将⼀个函数传递给另⼀个函数,同时在⼀⾏代码中定义这个被传递的函数。
正如我在《过度使⽤lambda表达式》中所写的,我不喜欢Python的lambda表达式语法。不管你是否喜欢这种语法,你都应该知道这种语
法只是创建函数的⼀种快捷⽅式。
每当你看到lambda表达式时,请记住:
表达式是⼀种特殊的语法,⽤于在⼀⾏代码中创建⼀个函数并将其传递给另⼀个函数
函数与所有其他函数对象⼀样:两者都没有⽐彼此特殊,都可以被来回传递
Python中的所有函数都可以作为参数传递给另⼀个函数(这恰好是lambda函数的唯⼀⽬的)。
⼀个常见的例⼦:键函数
除了内置的filter函数,你还在哪⾥可以看到⼀个函数被传递给另⼀个函数呢?可能你在Python中能看到这⼀点的最常见的地⽅就是使⽤key
函数的地⽅。
接受可排序/调整顺序的可迭代对象的函数通常也接受⼀个名为key的命名参数,这是⼀个普遍的约定。这个key参数应该是⼀个函数或另⼀个
可调⽤对象。
sorted、min和max函数都遵循这种接受⼀个key函数的约定:
对于给定的可迭代对象中的每个值,这个key函数都会被调⽤,并且其返回值会被⽤来对这个可迭代对象的每⼀个项进⾏order/sort。你可
以认为这个键函数是⽤来为该可迭代对象中的每个项计算⼀个⽐较键。
在上⾯的例⼦中,我们的⽐较键返回了⼀个⼩写的字符串,因此每个字符串都是通过它的⼩写版本(这就会导致⼀个⼤⼩写不敏感的顺序)进
⾏⽐较的。
我们使⽤了⼀个normalize_ca函数来做这件事,但是我们也可以使⽤ld来完成:
注意:如果你不熟悉类的⼯作⽅式,那么这种ld⽅法就会有点奇怪。类会存储未绑定的⽅法,这些⽅法在调⽤时将接受⼀个该类
的实例。我们通常会输⼊my_ld(),但是Python会将其转换为ld(my_string)。这就是另⼀个故事了。
这⾥我们找到了字母最多的字符串:
如果有多个最⼤值或最⼩值,最早的⼀个会胜出(这就是min/max的⼯作⽅式):
这是⼀个函数,它将返回⼀个2项元组,其中包含给定字符串的长度和该字符串的⼤⼩写归⼀化后的版本:
我们可以将这个length_and_alphabetical函数作为key参数传递给sorted,先按照字符串的长度对它们进⾏排序,然后在按照它们⼤⼩写
归⼀化后的表⽰形式进⾏排序:
这依赖于Python的排序操作符会进⾏深度⽐较这⼀事实。
其他将函数作为参数传递的例⼦
sort、min和max接受的key参数只是将函数传递给函数的⼀个常见⽰例。
另外两个接受函数的Python内置函数是map和filter。
我们已经看到了filter会根据⼀个给定函数的返回值来过滤列表。
map函数将在给定的可迭代对象中的每个项上调⽤这个给定的函数,并使⽤该函数调⽤的结果作为新的项⽬:
例如,这⾥我们把数字转换成字符串和对数字进⾏平⽅:
注意:正如我在关于过度使⽤lambda的⽂章中所指出的,我个⼈更喜欢使⽤⽣成器表达式,⽽不是map和filter函数。
与map和filter类似,还有来⾃itertools模块的takewhile和dropwhile函数。第⼀个类似于filter,只是它在找到断⾔函数为假的值时会停
⽌。第⼆个则相反:它只包含断⾔函数为假之后的值。
还有和late,它们都会调⽤⼀个2参数的函数来累计值,因为它们会进⾏循环:
collections模块中的defaultdict类是另⼀个例⼦。defaultdict类会创建类字典对象,当⼀个缺失的键被访问时,这些对象将不会引发⼀个
KeyError,⽽是⾃动向字典中添加⼀个新值。
这个defaultdict类接受⼀个可调⽤对象(函数或类),当⼀个缺失的键被访问时,它会被调⽤来创建⼀个默认值。
以上代码可以运⾏,因为在没有参数的情况下调⽤int会返回0:
这⾥的默认值是list,它在没有参数调⽤时会返回⼀个新列表。
functools模块中的partial函数是另⼀个例⼦。partial接受⼀个函数和任意数量的参数并返回⼀个新函数(技术上来说,它会返回⼀个可调⽤
对象)。
下⾯是partial的⼀个例⼦,它被⽤来将p关键字参数“绑定”到print函数:
现在返回的print_each函数所做的事情与使⽤p=''调⽤print⼀样:
你还会在第三⽅库中发现函数接受函数的例⼦,⽐如在Django和numpy中。每当你看到⼀个类或⼀个函数的⽂档声明它的⼀个参数应该是
⼀个可调⽤类型或⼀个可调⽤对象时,这意味着“你可以在这⾥传⼊⼀个函数”。
我要跳过的⼀个主题:嵌套函数
Python还⽀持嵌套函数(定义在其他函数内部的函数)。嵌套函数推动了Python的装饰器语法。
在本⽂中,我不打算讨论嵌套函数,因为嵌套函数要涉及到对Python中的⾮局部变量、闭包和其他奇怪的⽅⾯的探索,⽽当你刚开始将函
数作为对象处理时,你不需要知道这些⽅⾯。
我计划写⼀篇关于这个主题的后续⽂章,稍后我会在这⾥添加链接。同时,如果你对Python中的嵌套函数感兴趣,搜索⼀下Python中的⾼
阶函数可能会对你有帮助。
将函数视为对象是正常的
Python具有头等函数,这意味着:
1.你可以将函数赋值给变量
2.你可以将函数存储在列表、字典或其他数据结构
3.你可以将函数传⼊其他函数中
4.你可以编写返回函数的函数
将函数视为对象似乎有些奇怪,但这在Python中并不少见。据我统计,⼤约15%的Python内置函数都能接受函数作为参数(min、max、
sorted、map、filter、iter、property、classmethod、staticmethod、callable)。
Python的头等函数最重要的⽤途是:
1.将⼀个key函数传递给内置的sorted、min和max函数
2.将函数传递给像filter和ile这样的循环助⼿程序
3.将⼀个“默认值⽣成⼯⼚函数”传递给defaultdict之类的类
4.通过将函数传递给l来对它们进⾏“部分计算”
本文发布于:2023-03-10 10:09:33,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1678414174203006.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:我会在这里.doc
本文 PDF 下载地址:我会在这里.pdf
留言与评论(共有 0 条评论) |