1、函数的参数有哪些类型,分别怎么使用?
函数的参数类型可分为:必须参数、默认参数、可变参数(不定长参数)、关键字参数、组合参数,总共5种。
(1)必须参数:
>>>def hello(str):....
print('必须参数是:',str)
>>>hello('hello,world')
在函数hello中,str作为一个参数,是形参,形参的类型取决于调用时输入的实参类型
在定义函数时形参数量只有一个,因此在调用函数时传入实参也必须是一个
(2)默认参数:
默认参数就是定义函数时,形参给定一个值。
>>>def hs(name,age=23): ......
print('我叫:',name) ......
print('我今年',age)
>>>hs('王二',23)
默认参数可省略,如果在调用函数时输入了一个非默认形参值,这时候默认形参的值会发生变化,变为输入的那个值。
调用函数时也可以输入‘参数名=值’ 这样的形式,如hs(‘王二’,age=23)
!当存在默认参数和必须参数两种以上参数时,调用函数时一定要注意:
a : 调用函数时,实参的形式为都带参数名
b : 一个参数带参数名,另一个参数不带参数名,其中默认参数必须带参数名
c : 如果形参中默认参数在必须参数之前,那么调用函数时实参中默认参数也应当在前面;如果形参中默认参数在必须参 数之后,那么调用函数时实参中默认函数应当在后面,否则会报错。
(3)可变参数(不定长参数)元组形式打印
>>>def change(age,*som): print(age) for i in som: print(i) return >>>change('name','year','mon','address')
在形参中定义了两个参数,在实参中输入了4个参数还是正确的,是因为代码中实参name传给了形参age,而其余三个传给了*som,可以说som相当于一个无限大的容器,可以容纳很多个参数。
(4)关键字参数 字典形式打印
其实默认参数中已经出现了关键字参数。关键字参数就是在调用函数时,传入实参时带参数名,用这样的方式传入的实参叫做关键字参数。
①
dir = {'name': 'miss', 'age': '18'}def Deaf(school, banji, **other): print('学校:', school, '\n', '班级:', banji, '\n', '学生信息:', other)Deaf('清华', '大二', **dir)
学校: 清华
班级: 大二
学生信息: {'name': 'miss', 'age': '18'}
②
dir = {'name': 'miss', 'age': '18'}
def Deaf(school, banji, *other):
print('Xuexiao:', school, '\n', 'Banji:', banji, '\n', 'Student_info:', other)
Deaf('Tsinghua','Class 2',*dir)
Xuexiao: Tsinghua
Banji: Class 2
Student_info: ('name', 'age')
当形参中有不定长参数 *other,调用函数时用 *dir会发现结果是只有字典中键名,没有值!
③
dir = {'name': 'miss', 'age': '18'}def Deaf(school, banji, *other): print('Xuexiao:', school, '\n', 'Banji:', banji, '\n', 'Student_info:', other) Deaf('Tsinghua', 'Class 2', dir)
Xuexiao: Tsinghua
Banji: Class 2
Student_info: ({'name': 'miss', 'age': '18'},)
形参有不定长参数 *other ,调用函数时用 dir 但其结果是 将字典以元组的形式输出,即在字典外面加括号。
(5)组合参数
组合参数就是将之前讲过的4中参数同时引入函数作为形参,值得注意的是,定义参数时的顺序必须为:必须参数、关键字参数、默认参数、不定长参数。
①
xx = {'name': 'xiaozhi', 'age': '18', 'interesting': 'basketball'}tu = (1, 2, 3, 4, 5, 6)zd = {'m': 26, 'n': 25}def hs(a1, a2, a3=10, *a4, **cs): print('a1=', a1, 'a2=', a2, 'a3=', a3, 'a4a=', a4, cs) hs(1, 2, 3, 4, 5, 6, 7, m=26, n=25, **xx)
hs(*tu, **zd)
a1= 1 a2= 2 a3= 3 a4a= (4, 5, 6, 7) {'m': 26, 'n': 25, 'name': 'xiaozhi', 'age': '18', 'interesting': 'basketball'}
a1= 1 a2= 2 a3= 3 a4a= (4, 5, 6) {'m': 26, 'n': 25}
在第一次调用函数时,1、2分别给a1,a2,形参a3=10,但是传入实参为3,改变了原来的值,因此a3=3,*a4 是不定长参数,因此4、5、6、7给*a4,因此a4a是多个值,以元组的形式输出,**cs为关键字参数,所以m、n以及**xx 的值给**cs,以字典形式输出。
在第二次调用函数时,tu为一个元组,调用时用*tu方法,因此a1=1,a2=2,a3=3,a4a=(4,5,6);用**zd调用时以字典形式输出。
def fn(x, y, n, z=3, m=4, *args, **kwargs): print(x, y, z, m, n) print(args) print(kwargs)fn(1, 2, 4, 5, 6, n=1)fn(a=10, b=20, n=30, m=40, y=50, x=60)
fn(1, 2, 4, 5, 6, n=1)此句中给n传入实参之后又对n赋值,报错
def fn(x, y, n, z=3, m=4, *args, **kwargs): print(x, y, z, m, n) print(args) print(kwargs)# fn(1, 2, 4, 5, 6, n=1)fn(a=10, b=20, n=30, m=40, y=50, x=60)
60 50 3 40 30
()
{'a': 10, 'b': 20}
必须参数不能重复赋值会报错,默认参数值可以改变
2、比较如下两端代码,说明各自输出结果并说明原因。
①
b = 100
print(id(b))
def test0(m):
print(id(m))
m += 100
print(id(m))
print(m)
test0(b)
print(b)
140728508604544
140728508604544
140728508607744
200
100
b为num时:当b作为实参传入函数中,对b做出运算后,产生新的值,具有与b不同的id值;b本身的值不变,id值不变。
②
b = [1, 2]
print(id(b))
def test0(m):
print(id(m))
m.append(3)
print(id(m))
print(m)
test0(b)
print(b)
2989174841928
2989174841928
2989174841928
[1, 2, 3]
[1, 2, 3]
b为列表时:当b作为实参传入函数中时,对b做出运算后,改变b本身的值,b的id值不变。