前言
python作为一门高级语言,其一个重要的特征就是 “灵活” 。例如在函数的参数这方面,除了普通的位置参数之外还涉及了“默认参数”、“可变参数”、“关键字参数”之类的概念。
今天我们就一起看看除了位置参数之外,python的“参数”还能玩出什么花样~”
文假设我们已经有如何定义一个函数的基础知识储备。但是如果对这个概念不大熟悉的话也不要紧,我们简要介绍一下
1.函数定义与位置参数
我们可以用def语句定义一个函数:
def function(x,y): <code>
如上,我们就定义了一个名字叫function的h函数(函数名可以自由取),x,y就是我们的位置参数,会默认按照x,y的顺序将你输入的数据赋值给函数变量。
2.默认参数
在使用函数的时候,如果发现一种参数需要反复重复地输入,这就很妨碍程序员的coding效率(也很影响心情)。
有没有可能在定义的时候就让我们的函数知道,如果没有特殊指定,某个参数就按照预设的值赋值
显然是有的,这就是“默认参数”
def function(x,y=10): <code>
这样一来,我们调用函数的时候如果输入的是function(5),那么实际上计算机调用的是function(5,10)。这样就省去了可能在调用function的时候反复赋值y的情况。或者这个y非常重要,不赋值可能造成程序出错等严重结果
3.可变参数
这时候问题又来了。既然python是个“灵活”的语言,那我们是不是不需要在定义的时候就明确设置好需要的参数呢?
在实际生活当中,有些输入就是不定的,比如有些人有很多爱好,有些人计划没爱好;大部分学生可能就一个专业,但也有一些双修三修的大佬……
都用if来构造分支语句吗?不够灵活
python支持设置可变参数,把所有未匹配的位置参数组成一个tuple元组对象,用我们定义的可变对象名作为局部变量指向这个元组。
具体是什么意思呢?
def func(*args): <code>
我们不论输入的是func(1)
还是func(1,2,3,4)
,这些数据都会存成一个元组,用args指向这个元组。
def func(*args): print(args)
如上,我们这样写了之后如果调用func(1,2,3,4)
,那我们就能看到(1,2,3,4)
这个输出。
当我们输入了一个序列类型的数据时,就可以很好地利用序列的操作进行运算了,比如:
def calclu(x,*y): return x*sum(y)
如此就可以计算函数输入的第一个数字乘之后全部数字之和了,此时我们不需要知道之后的数字有多少个。
4.关键字参数
可变参数感觉实际上是“位置参数”加上了“可变”的特性。我们知道传入的参数可以不按照位置来定,你可以在调用函数的时候通过指定一个参数的名字来把值赋给它,我们把这样传入的参数叫做“关键字参数”。
那有没有类似这样的“关键字参数”的“可变参数”呢?
显然是有的。
def func(**kw): print(kw) >>>func(a=1,b=2) {"a":1,"b":2}
func(a=1,b=2)
当我们这样调用函数的时候,得到的输出是一个字典。的确,关键字参数数据在传入的时候,会优先匹配和位置参数对上的参数,然后把剩下没匹配上的参数统一打包成dict字典并传入,用**
后面的参数指向这个字典。
我们再看一个例子:
def func(a,**b): print(a) print(b) >>>func(a=1,b=2,c=3) 1 {"b":2,"c":3}
很直观,因为在传入的时候a匹配上了我们之前定义的位置参数,所以1赋值给a变量;
b,c没有在位置参数中出现,又是以关键字参数的形式传入的。我们把它封装成一个字典。
这样一来,python就更加灵活了。我们除了可以处理不知道数量的数据之外,还可以允许给不定数量的参数添加信息
def func(name,**kw): print(f"{name},{kw}") >>> func("小明",age=18,gender="male") 小明,{"age":18,"gnder":"male"}
是不是很直观?如此灵活的语言,印证了那句话:
人生苦短,我学python