可变参数
假设我们有这样的一个字典,存储学生年龄,如下:
studentInfo = {
'张飞' : 18,
'赵云' : 17,
'许褚' : 16,
'典韦' : 18,
'关羽' : 19,
}
要实现一个函数 printAge
,它的输入参数是一些学生的姓名,函数需要打印出这些输入学生的年龄。
这里有个问题,就是调用printAge 时, 输入的学生名字 个数是不固定的,可能是1个、2个、100个, 甚至也可能是0个。
这肯定难不倒聪明的你, 你一番思考,决定使用列表作为参数类型, 列表里面每个元素存放要获取年龄信息的学生名。
像这样
studentInfo = {
'张飞' : 18,
'赵云' : 17,
'许褚' : 16,
'典韦' : 18,
'关羽' : 19,
}
def printAge(students) :
for student in students:
print( f'学生:{student} , 年龄 {studentInfo[student]}')
printAge(['张飞', '典韦', '关羽'])
printAge(['赵云'])
运行一下看看, 完全没有问题。
但是我们似乎觉得,如果调用该函数的时候,能把下面这种写法
printAge(['张飞', '典韦', '关羽'])
改为
printAge('张飞', '典韦', '关羽')
这样调用。 显得更加易读易懂。
但是问题就在于,因为这个函数参数的个数是不确定的,函数如何定义呢?
Python中可以这样定义
def printAge(*students) :
for student in students:
print( f'学生:{student} , 年龄 {studentInfo[student]}')
和上面相比,唯一的改动就是, 参数名前面加了一个星号。
然后我们就可以这样调用该函数了
printAge('张飞', '典韦', '关羽')
printAge('赵云')
效果和前面一种定义完全一样。
这种前面加一个星号的参数,称之为可变参数,
在调用该函数的时候,Python解释器会创建一个 tuple 赋值给这个参数变量。并且会把 传入的数据对象 放到这个tuple对象里面。
也就是说,上面的例子里面,如下调用代码执行的时候,
printAge('张飞', '典韦', '关羽')
Python解释器创建一个 tuple 赋值给这个 students,里面存放了 ‘张飞’, ‘典韦’, ‘关羽’ 三个字符串对象作为元素,
我们在代码里加入一行语句,显示 students 类型
studentInfo = {
'张飞' : 18,
'赵云' : 17,
'许褚' : 16,
'典韦' : 18,
'关羽' : 19,
}
def printAge(*students) :
print(type(students))
for student in students:
print( f'学生:{student} , 年龄 {studentInfo[student]}')
printAge('张飞', '典韦', '关羽')
运行结果显示
<class 'tuple'>
学生:张飞 , 年龄 18
学生:典韦 , 年龄 18
学生:关羽 , 年龄 19
说明 students变量确实是对应一个tuple对象。
printAge 使用上面这样的可变参数,假如我们要传入的参数恰好已经在一个list(或者tuple) 中,比如
onebatch = ['张飞', '典韦', '关羽']
怎么调用printAge呢?
当然可以这样
printAge (onebatch[0], onebatch[1], onebatch[2])
显然不方便。
其实,我们可以这样
printAge(*onebatch)
在调用时,这就是参数展开。
我们可以将其等价于
printAge (onebatch[0], onebatch[1], onebatch[2])
大家注意,这里是在调用函数的时候,传入参数前面加上星号,是参数展开;
前面我们讲的可变参数是在函数定义的时候前面加上星号。
大家不要搞混了。
关键字可变参数
参数个数不确定,除了上面这种定义的方式,还有另外一种定义方式,叫做关键字可变参数。
比如,我们要实现一个函数,可以在 学生年龄表里面添加新的学生信息, 可以输入不定数量的学生信息,包括姓名和年龄。
可以这样定义
def addStudents(table,**students):
print(type(students))
for name,age in students.items():
table[name] = age
table1 = {}
table2 = {}
addStudents(table1, 李白=20, 杜甫=24)
addStudents(table2, Jodan=45, James=32, onil=40)
print(table1)
print('----------------')
print(table2)
运行一下,输出结果如下
<class 'dict'>
<class 'dict'>
{'李白': 20, '杜甫': 24}
----------------
{'Jodan': 45, 'James': 32, 'onil': 40}
其中 <class 'dict'>
说明了 前面有两个星号 的 参数变量 students
的值是一个字典。
这种前面加2个星号的参数,称之为关键字可变参数,
在调用该函数的时候,Python解释器会创建一个 dict (字典) 赋值给这个参数变量。
并且会把 传入的数据对象 分别放到这个dict 对象里面。
传入的参数对象,必须是像 name=value
这种 带参数名和参数值的, 放到dict对象时,参数名是字典元素的key,参数值是字典元素的value。
也就是说,上面的例子里面,如下调用代码执行的时候,
addStudents(table1, 李白=20, 杜甫=24)
Python解释器创建一个 字典 赋值给参数变量 students,把 李白,20
和 杜甫,24
作为 2个键值对元素放到 该字典中。
addStudents 使用上面这样的关键字可变参数,假如我们要传入的参数恰好已经在一个字典 中,比如
onebatch = {'李白': 20, '杜甫': 24}
怎么调用addStudents呢?
可以这样参数展开
onebatch = {'李白': 20, '杜甫': 24}
addStudents(table1, **onebatch)
和上面不同的是,对字典,要使用两个星号进行参数展开,Python解释器会把字典里面,每个元素的键作为参数名,值作为参数值,这样进行函数调用