摘要:调用函数时,必须传入且传入的两个值按照位置顺序依次赋给参数和,若缺省,则会报错。例如二默认参数在函数定义中,为参数预先定义默认值。执行相当于调用如果要求的四次方,则需要执行设置默认参数的好处默认参数可以简化函数的调用,降低调用函数的难度。
题外话:因为时间关系,没能保持一定的更新频率。但还是会一直坚持的~
之前介绍了Python函数的定义,今天分享一下Python函数的参数吧!内容会有点多~
Python的函数定义比较简单,借助于关键字def进行实现,但是参数的灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数、关键字参数、命名关键字参数以及参数组合,这使得函数定义出来的接口,不仅能处理复杂的参数,还能简化调用者的代码。
在函数定义的时候,指定参数的位置顺序。位置参数必须在被调用函数定义中的准确顺序来进行传递。
例如:计算x的n次方
def powern(x,n): s = 1 while n >0: s = s * x n = n -1 return s
x与n这两个参数都是位置参数。调用函数时,必须传入且传入的两个值按照位置顺序依次赋给参数x和n,若缺省,则会报错。例如:
>>> powern(5) Traceback (most recent call last): File "二、默认参数", line 1, in TypeError: powern() missing 1 required positional argument: "n"
在函数定义中,为参数预先定义默认值。当在函数调用时,若没有为参数提供指定值,则使用默认值。
例如:仍旧是求x的n次方,但是默认为x的3次方。
def powern( x,n = 3): s = 1 while n >0: s = s * x n = n -1 return s
执行:powern(2),相当于调用powern(2,3)
如果要求2的四次方,则需要执行:powern(2,4)
设置默认参数的好处?
默认参数可以简化函数的调用,降低调用函数的难度。无论是简单调用还是复杂调用,函数只需定义一个。
例如上述powern()的例子,当传入n的其他值时,则可以实现x的其他n次方。
但是在使用默认参数的时候,如果使用不当,也会有坑。先来了解一下可变参数和不可变参数作为函数参数时的不同:
不可变参数作为函数参数
>>> a = 1 >>> def func(a): ... print("func_id:",id(a)) ... a = 2 ... print("after_func_id:",id(a),"id(2):",id(2)) ... >>> print("out_of_func_id:",id(a),"id(1):",id(1)) out_of_func_id: 501962480 id(1): 501962480 # 全局变量a的id >>> func(a) # 将全局参数a传入函数 func_id: 501962480 # a=1 的id after_func_id: 501962496 id(2): 501962496 >>> print(a) # 退出函数,a的值仍为1 1
当把全局a传递给函数后,函数自动复制一份引用。执行完a=2之后,id(a)的内存地址发生变化。但是跟外层的a没有关系。
可变对象作为函数参数
>>> a = [] >>> def func2(a): ... print("func2_id:",id(a)) ... a.append(1) ... >>> print("out_of_func2_id",id(a)) out_of_func2_id 59694296 >>> func2(a) func2_id: 59694296 >>> print(a) [1]
变量a的类型为list,是可变对象。函数的引用指向的是可变对象,地址没有发生变化,所以函数操作后,a的内容发生了改变。
所以当再次操作func2(a)函数时,产生跟预期不一样的结果:
>>> func2(a) func2_id: 59694296 # a地址不变 >>> print(a) [1, 1] # 因为第一次执行func2(a)时,已经修改了a=[1],再次调用时,在[1]里新增
使用可变对象作为默认参数
例如:
def add_end( L=[] ): # 设置为一个list变量L(对象可变) L.append("end") return L >>> add_end( ) ["end"] >>> add_end() ["end", "end"]
当连续重复使用默认参数调用时,结果出现错误。
Python函数在定义的时候,默认参数L的值就被计算出来了,即[]。L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
可以改为:
def add_end( L=None ): # L为不变对象 if L is None: L = [] L.append("end") return L
则无论调用多少次,都不会出现问题。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁。
设置默认参数时,有几点需要注意
一.必选参数在前,默认参数在后,否则Python的解释器会报错。
二.如何设置默认参数?当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
三.不要使用可变对象作为默认参数。
可变参数,即传入的参数个数是可变的,0至任意个。
因为参数个数不确定,则可以使用一个list 或者tuple传进来。之后在函数调用时会自动组装为一个tuple。
例如:
def calc(numbers): # 变量 sum = 0 for n in numbers: sum = sum + n * n return sum >>> calc( [1,2,3] ) # 传入的是一个list 14
利用可变参数 *args:
def calc( *numbers ): sum = 0 for n in numbers: # 在函数内部,numbers组装成一个tuple sum = sum + n * n return sum >>> calc( ) # 0个参数 0 >>> calc( 1,3,5,7 ) # 多个参数 84 >>> num = [1,2,3] # list >>> calc( *num ) # *list –> tuple 14 >>> t = (1,3,5) >>> calc( t ) # tuple(错误) Traceback (most recent call last): File "", line 1, in File " ", line 4, in calc TypeError: can"t multiply sequence by non-int of type "tuple" >>> calc( *t ) 35
函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数。
四、关键字参数**kw关键字参数**kw允许传入0个至任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。例如:
def person(name , age , **kw ): print("name:",name,"age:",age,"other:",kw) >>> person("xiong",18) name: xiong age: 18 other: {} >>> person("xiong",18,city = "SH") # city是原本没有的参数,但是因为有**kw name: xiong age: 18 other: {"city": "SH"}
关键参数有什么用?可以扩展函数的功能。比如在person()函数里面,可以保证接收到name和age这两个参数。但是如果提供更多参数,也能收到。当然也可以先组装一个dict,再把该dict转换为关键字参数传递进去:
>>> extra ={"city":"shanghai","job":"SET"} # dict的定义 >>> person("xiong",18,city = extra["city"],job=extra["job"]) # dict的使用 name: xiong age: 18 other: {"city": "shanghai", "job": "SET"} # dict的内容 >>> person("xiong",18,**extra) name: xiong age: 18 other: {"city": "shanghai", "job": "SET"}
【总结】**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
五、命名关键字参数如果要限制关键字参数的名字,就可以用命名关键字参数。需要一个特殊分隔符“”,“”后面的参数被视为命名关键字参数。如果缺少“*”,Python解释器则无法识别位置参数和命名关键字参数。在调用时,必须指定参数名字与参数值。
例如,只接收city和job作为关键字参数,可以使用如下定义:
def person( name ,age,*,city,job): print(name , age , city , job ) >>> person("xiong", 18, city="shanghai", job="tester") xiong 18 shanghai tester
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
>>> def person( name,age,*args,city,job ): # 此处city和job也是命名关键字参数 ... print(name, age, city, job)
命名关键字参数必须传入参数名,如果没有传入参数名,调用将会报错:
>>> person("xlp",18,"shanghai","tester") # 错误调用 Traceback (most recent call last): File "", line 1, in TypeError: person() missing 2 required keyword-only arguments: "city" and "job" >>> person("xlp",18,city="shanghai",job="tester") # 正确调用 xlp 18 shanghai tester
命名关键字参数可以有缺省值,从而简化调用:
>>> def person1(name,age,*,city="shanghai",job): ... print(name,age,city,job) ... >>> person1("xlp",18,job="engineer") xlp 18 shanghai engineer六、参数组合
在Python中定义函数,可以用位置参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。
但是要注意,参数定义的顺序必须是:位置参数、默认参数、可变参数、命名关键字参数和关键字参数。
(1)定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个list、tuple;
**kw是关键字参数,kw接收的是一个dict;
(2)调用函数时如何传入可变参数和关键字参数的语法:
可变参数直接传入:func(1,2,3)
可变参数间接传入:先组装成list或tuple,l=(1,2,3),再通过args传入,func(l)
关键字参数直接传入:func(a=1,b=2)
关键字参数间接传入:先组装成dict,d={‘a’:1,’b’:2},再通过kw传入,func(d)
(3)命名关键字参数 是为了限制调用者可以传入的参数名,同时可以提供默认值。
(4)定义命名的关键字参数在没有可变参数的情况下,不要忘记写分隔符*,否则定义的将是位置参数。
❤ thanks for watching, keep on updating...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/42370.html
摘要:在定义函数时给定的名称称作形参,在调用函数时你所提供给函数的值称作实参。调用函数要调用一个函数,需要知道函数的名称和参数。默认参数值可以有效帮助解决这一情况。是默认参数定义默认参数要牢记一点默认参数必须指向不变对象。 关于数据科学在做什么,我们已经在前两篇文章中进行了总结,即专题概述和描述性统计分析。要进行数据科学的探索,需要一个好工具,就是Python。从本篇开始,将总结学习Pyth...
摘要:调用以回调函数地址为参数的函数这个主题就稍微绕一些了,也就是说在接口中,需要传入回调函数作为参数。这个问题在中也可以解决,并且回调函数可以用定义。代码代码很简单回调函数的传入参数为,返回参数也是。 项目中要对一个用 C 编写的 .so 库进行逻辑自测。这项工作,考虑到灵活性,我首先考虑用 Python 来完成。 研究了一些资料,采用 python 的 ctypes 来完成这项工作。已经...
摘要:主要是库文件头文件文件不一致的问题。定义模块函数其中函数参数是模块自身,是传递的参数列表,返回值定义了一个整形数,这里会申请空间增加引用计数,交由来管理这个引用。 C++开发python windows版本的扩展模块示例测试环境介绍和准备测试环境:操作系统:windows10Python版本:3.7.0VS版本:vs2015社区版(免费)相关工具下载:VS版本vs2015社区版(免费)...
摘要:主要是库文件头文件文件不一致的问题。定义模块函数其中函数参数是模块自身,是传递的参数列表,返回值定义了一个整形数,这里会申请空间增加引用计数,交由来管理这个引用。 C++开发python windows版本的扩展模块示例测试环境介绍和准备测试环境:操作系统:windows10Python版本:3.7.0VS版本:vs2015社区版(免费)相关工具下载:VS版本vs2015社区版(免费)...
摘要:函数返回值支持多个,返回多个时,使用逗号分隔。如上,与这个参数按照由左到右依次赋值给形参和供函数内部使用。在传入函数时,便是将这个引用传入了函数。需要使用关键字声明将变量作用域变为函数外部非全局变量,及闭包作用域。 < 返回索引页 函数 函数定义 返回值 函数的调用 函数的参数 顺序参数 参数的默认值 可变参数 关键字参数 参数的组合 参数的专递 函数作用域 内建...
摘要:为我们提供了许多内置函数,例如并提供了创建用户定义函数的能力。会将该变量视为函数级作用域中的局部变量。回到目录中函数的用途是什么是中的内置函数之一。请注意,这种类型的参数语法不允许将命名参数传递给函数。函数接受一个称为的可选参数。 ...
阅读 888·2021-10-13 09:48
阅读 3787·2021-09-22 10:53
阅读 3069·2021-08-30 09:41
阅读 1915·2019-08-30 15:55
阅读 2890·2019-08-30 15:55
阅读 1798·2019-08-30 14:11
阅读 2137·2019-08-29 13:44
阅读 719·2019-08-26 12:23