本文简洁明了,辅以代码进一步加深理解。递归函数当函数调用自身以产生最终结果时,这样的函数称为递归函数。有时递归函数非常有用,因为它们使编写代码更容易——一些算法使用递归范式很容易编写,而另一些则不然。没有不能迭代重写的递归函数,换句话说,所有递归函数都可以用循环迭代实现,所以通常由程序员根据手头的情况选择最好的方法。一个递归函数体通常有两部分:一部分的返回值取决于后续对自身的调用,另一部分的返回值不依赖于后续对自身的调用(称为基本情况,或递归边界)。作为理解的参考例子,我们来看一个阶乘函数N!作为递归的两部分:基本情况(边界,用于结束递归)是当N为0或1时,函数返回1,不需要进一步计算。另一方面,一般情况下的自调用,N!返回生成的结果:1*2*...*(N-1)*N仔细想想,N!可以这样写:N!=(N-1)!*N。作为一个实际示例,请看以下阶乘表示:5!=1*2*3*4*5=(1*2*3*4)*5=4!*5我们把它转换成函数实现:#阶乘递归函数实现deffactorial(n):ifnin(0,1):#递归边界return1returnfactorial(n-1)*n#递归调用masterheroes写算法的时候经常用到递归函数,写递归函数很有意思。作为练习,尝试使用递归和迭代方法解决一些简单的问题。一个很好的练习可能是计算斐波那契数列或类似的东西。自己试试吧。提示:在编写递归函数时,请始终考虑您将进行多少次嵌套调用,因为这是有限制的。有关这方面的更多信息,请参阅sys.getrecursionlimit()和sys.setrecursionlimit()。匿名函数另一个函数是匿名函数(Anonymousfunctions)。这些函数在Python中称为lambda,通常在使用具有自己完全定义的名称的函数是多余的时使用,而所需要的只是一个快速、简单的一行代码来完成这项工作。假设我们想要一个所有N个值都是5的倍数的列表。为此,我们可以使用filter()函数,它以一个函数和一个可迭代对象作为输入。返回值是一个过滤器对象,当您对其进行迭代时,它会从输入可迭代对象中生成元素,所需参数函数为其返回True。我们可能不使用匿名函数,而是这样做:defisMultipleOfFive(n):returnnotn%5defgetMultipleOfFive(n):returnlist(filter(isMultipleOfFive,range(n)))注意我们是如何使用isMultipleOfFive()来过滤的前n个自然数。这似乎有些矫枉过正——任务非常简单,我们不需要为其他任何事情保留isMultipleOfFive()函数。此时,我们可以用lambda函数重写:#lambdafilterdefgetMultiplesOfFive(n):returnlist(filter(lambdak:notk%5,range(n)))逻辑完全一样,但是filterfunction现在是lambda函数,显然Lambda更简单。定义Lambda函数非常简单,它遵循以下形式:funcName=lambda[parameter_list]:expression它返回一个函数对象,相当于:deffunc_name([parameter_list]):returnexpression参数列表由分隔逗号。注意,可选参数是方括号括起来的部分,是通用语法的表达,即文中方括号中的部分是可选的,根据实际需要提供。让我们看看其他两个等价函数的例子。类型定义:#lambdadescription#例1:两个数相加defadder(a,b):returna+b#等价于:adder_lambda=lambdaa,b:a+b#例2:字符串转大写defto_upper(s):returns.upper()#等价于:to_upper_lambda=lambdas:s.upper()前面的例子很简单。第一个函数将两个数字相加,第二个函数生成字符串的大写版本。请注意,我们将lambda表达式返回的内容分配给一个名称(adder_lambda、to_upper_lambda),但是在filter()示例中使用lambda时不需要这样做——无需将匿名函数分配给变量。函数属性Python中的每个函数都是一对完整的函数。因此,它具有许多特性。其中一些是特殊的,可以在运行时以内省的方式检查函数对象。下面是一个例子,展示了其中的一些以及如何为示例函数显示它们的值:#Functionattributesdefmultiplication(a,b=1):"""Returnsamultipliedbybstructure."""returna*bif__name__=="__main__":special_attributes=["__doc__","__name__","__qualname__","__module__","__defaults__","__code__","__globals__","__dict__","__closure__","__annotations__","__kwdefaults__",]forattributeinspecial_attributes:print(attribute,'->',getattr(multiplication,attribute))我们使用内置的getattr()函数来获取这些属性的值。getattr(obj,attribute)等同于obj.attribute,当我们需要在运行时动态获取属性时它会派上用场,我们从变量中获取属性的名称(如本例所示)。运行此脚本将得到类似于以下内容的输出:__doc__->返回a乘以b.__name__的结果->multiplication__qualname__->multiplication__module__->__main____defaults__->(1,)__code__-><...>__globals__->{...略...}__dict__->{}__closure__->None__annotations__->{}__kwdefaults__->None这里省略了__globals__属性的取值,内容太多。该属性的含义可以在Python数据模型文档页面的callabletype部分找到(或者内置帮助文档):https://img.ydisp.cn/news/20221112/t4zi3ugyuad.htmlid="hce1b53f-RkQ8YfpF"data-id="hce1b53f-195Q8lpk">内置函数Python带有许多内置函数。它们可以在任何地方使用,你可以通过dir(__builtins__)查看builtins模块,或者通过访问官方Python文档来获取它们的列表。这里就不一一介绍了。在前面的学习过程中,我们已经见过其中的一些,比如any、bin、bool、divmod、filter、float、getattr、id、int、len、list、min、print、set、tuple、type和zip等.,但还有更多,我建议您至少阅读一次。熟悉它们,试用它们,为它们中的每一个编写一小段代码,并确保您随时可以使用它们,以便在需要时可以使用它们。这个内置函数列表可以在官方文档中找到:https://img.ydisp.cn/news/20221112/1fypeqzy4ne.html。文档化代码我们非常喜欢不需要文档化的代码。当我们正确编程、选择正确的名称并注意细节时,代码应该是不言自明的,几乎不需要文档。但是,有时注释非常有用,就像添加一些文档一样。您可以在Python的PEP257规范-Docstring约定中找到Python的文档指南:https://www.python.org/dev/peps/pep-0257/,但仍会参考Youshowthefundamentals。Python的文档由字符串组成,恰当地称为文档字符串。可以使用单行或多行文档字符串记录任何对象以描述记录。单线非常简单。它不应为函数提供另一个签名,而应说明或描述函数的目的。请参见下面的示例:#简单的文档化代码defsquare(n):"""Function:Returnsthesquareofanumbern."""returnn**2defget_username(userid):"""Function:ReturnsthegivenUsernameforid."""returndb.get(user_id=userid).username使用三重双引号字符串可以方便以后扩展或扩充文档内容。使用以句点结尾的句子,前后不要留空行。多行注释具有类似的结构。应该有一行简单的代码说明对象的要点,然后是更详细的描述。作为多行文档的示例,我们使用Sphinx表示法来记录虚构的connect()函数,并在以下示例中记录描述:#multi-linedocumentedcodedefconnect(host,port,user,password):"""功能:连接数据库,返回连接对象。使用以下参数直接连接PostgreSQL数据库。:paramhost:主机IP。:paramport:端口。:paramuser:连接用户名。:parampassword:connectionpassword.:return:Connectionobject."""#Functionbody...returnconnection提示:Sphinx是使用最广泛的创建Python文档的工具之一——事实上,官方的Python文档就是用它编写的。绝对值得花时间去看看。内置函数help()旨在用于即时交互使用,它使用对象的文档字符串为对象创建文档页面以显示对象的使用方式。基本用法如下:defsquare(n):"""功能:返回数n的平方。"""returnn**2help(square)__main__:square(n)模块中函数square的帮助功能:返回数n的平方。首先,指定或定义一个对象或函数(包括已有的对象或函数),然后使用内置的help函数,将对象或函数作为help的参数,函数会返回对应对象的文档,就这么简单,本文总结了一些相关主题,在一个基础上展开Python语言的主要特征——函数编程知识,包括递归函数(关注有限性和边界性)、lambda函数(简洁性和临时性),以及函数的性??质和如何实现函数的文档化描述等。
