当前位置: 首页 > 后端技术 > Python

Python基础:函数简介

时间:2023-03-26 00:20:53 Python

函数是结构化编程的基础,是代码复用的基石。Python使用def来定义函数。本文将深入探究Python中函数的秘密。内置函数除了用户自定义的函数,Python还内置了一些非常有用的函数:自定义函数使用def定义Python中的函数,使用return返回特定的值。看一个简单函数的例子:defmy_function(x,y,z):ifz>1:returnz*(x+y)else:returnz/(x+y)就拿我们前面讲的斐波那契数列来说sequenceexample被重新定义为一个函数,可以这样写:deffib(n):a,b=0,1whilea1:returnz*(x+y)else:returnz/(x+y)这样我们在调用my_function的时候只能传两个参数,最后一个z可以使用默认参数值。请注意,默认值只会执行一次。如果你传入的参数是可变对象(列表、字典和类实例),我们需要注意这个问题:deff(a,L=[]):L.append(a)returnLprint(f(1))print(f(2))print(f(3))#output[1][1,2][1,2,3]如果你不想在后续调用中共享默认值,那么你可以将默认值赋值放在函数体内:deff(a,L=None):ifLisNone:L=[]L.append(a)returnLkeywordparameterwecanusekey=Valuewaytocallthefunction.还是之前的函数:defmy_function(x,y,z=10):ifz>1:returnz*(x+y)else:returnz/(x+y)我们可以这样调用:my_function(1,y=3,z=5)my_function(1,y=3)但是不能这样用:my_function(y=3,1)关键字的参数必须放在非关键字参数的后面。也不能对参数进行多次赋值:>>>deffunction(a):...pass...>>>function(0,a=0)Traceback(mostrecentcalllast):File"",line1、inTypeError:function()gotmultiplevaluesforkeywordargument'a'通过上面的讨论,我们可以看出Python函数中有两种参数,一种是有默认值的参数,还有另一个是One是没有默认值的参数。注意没有默认值的参数必须在有默认值的参数之前。看一个错误的例子:In[69]:deffa(a=100,b,c=200):...:passFile"",line1deffa(a=100,b,c=200):^SyntaxError:non-defaultargumentfollowsdefaultargument给函数传递参数有两种方式,一种是不带关键字传递,另一种是带关键字传递。注意非关键字参数必须在传递关键字参数之前传递。错误示例:In[70]:deffa(a,b=100,c=200):...:pass...:In[71]:fa(a=100,30)File"",line1fa(a=100,30)^SyntaxError:positionalargumentfollowskeywordargument那么问题来了,如果有多个关键字参数和多个非关键字参数,有没有什么定义这样一个函数的简单方法?是的,就是arguments和*keywordsarguments用来接收所有冗余的非关键字参数。并且*keywords用于接收所有其他关键字参数。请注意,参数必须出现在*关键字之前。例如:defcheeseshop(kind,*arguments,**keywords):print("--你有什么",kind,"?")print("--对不起,我们都没有了",kind)forarginarguments:print(arg)print("-"*40)forkwinkeywords:print(kw,":",keywords[kw])我们可以这样调用:cheeseshop("Limburger",“它非常稀,先生。”,“它真的非常非常稀,先生。”,shopkeeper="MichaelPalin",client="JohnCleese",sketch="CheeseShopSketch")将得到以下结果:--你有Limburger吗?--对不起,我们都没有Limburger太稀了,先生。真的非常非常流鼻涕,先生。------------------------------------店主:MichaelPalinclient:JohnCleesesketch:CheeseShopSketch特殊参数函数可以按位置传参,也可以按关键字传参,也可以混合传参。在某些情况下,我们可能需要限制传递的参数类型,比如只接受位置传递,只接受关键字传递,或者只接受混合传递。看特殊参数的定义:deff(pos1,pos2,/,pos_or_kwd,*,kwd1,kwd2):------------------------------||||按位置或关键字||-只允许按关键字传递--只允许按位置传递注意参数以/和*区分。让我们举个例子:>>>defstandard_arg(arg):...print(arg)...>>>defpos_only_arg(arg,/):...print(arg)...>>>defkwd_only_arg(*,arg):...print(arg)...>>>defcombined_example(pos_only,/,standard,*,kwd_only):...print(pos_only,standard,kwd_only)上面定义了4个传统函数参考模式。第一个函数是标准形式,可以按位置或按关键字传递。第二个函数只允许按位置传递。第三个函数只允许通过关键字传递。第四个功能是混合模式。参数解包有时我们需要将列表或字典值转换为函数参数。那么就需要用到参数解包的功能了。*运算符可用于解包列表和元组。>>>list(range(3,6))#带有单独参数的正常调用[3,4,5]>>>args=[3,6]>>>list(range(*args))#带有参数的调用unpackedfromalist[3,4,5]**运算符可用于解包字典。>>>defparrot(voltage,state='astiff',action='voom'):...print("--这只鹦鹉不会",action,end='')...print("如果你把",voltage,"voltsthroughit.",end='')...print("E's",state,"!")...>>>d={"voltage":"四百万","state":"bleedin'demised","action":"VOOM"}>>>parrot(**d)Lambda熟悉java的朋友可能知道,在JDK8中,Java引入了Lambda表达式。同样,Lambda在Python中也可用。您可以将Lambda视为匿名函数。Lambda表达式可以用在任何需要函数的地方。看一个Lambda例子:>>>defmake_incrementor(n):...returnlambdax:x+n...>>>f=make_incrementor(42)>>>f(0)42>>>f(1)43也可以使用lambda的返回值作为参数:>>>pairs=[(1,'one'),(2,'two'),(3,'three'),(4,'four')]>>>pairs.sort(key=lambdapair:pair[1])>>>pairs[(4,'four'),(1,'one'),(3,'three'),(2,'二')]在函数注解之前,我们讨论了简单的自定义函数形式。我们不知道函数的参数类型和返回值类型。其实函数可以写的更详细一些,这就需要函数注解了。所谓函数注解就是用户自定义函数中类型的可选元数据信息。函数注释以字典的形式存储在annotations属性中。我们在参数名称后面放一个冒号,后面跟着一个表达式,那么这个表达式就会被计算为注解的值。对于返回值,通过添加组合符号->后跟形式参数列表和标记def语句结束的冒号之间的表达式来定义返回值注释。例如:>>>deff(ham:str,eggs:str='eggs')->str:...print("Annotations:",f.__annotations__)...print("Arguments:",ham,eggs)...returnham+'and'+eggs...>>>f('spam')Annotations:{'ham':,'return':,'eggs':}参数:spameggs'spamandeggs'其实用函数注解写出来的程序更清晰可读。