一、形参和实参
实参
在函数调用()中出现的参数(外界实际存在的值):实参。值可以为常量、变量、表达式或三者的组合
形参
在函数定义()中出现的参数:形参。形参就是拷贝实参的值,随着函数的调用才产生,随着函数调用结束而销毁。
在函数的外部不能直接使用函数的形参,因为函数调用完毕后,形参被销毁了。
二、实参分类
def fn1(a, b, c):
print(a, b, c)
位置实参
必须按照位置的顺序,从左到右为形参传递值
fn1(10, 20, 30) # 10 20 30
fn1(30, 20, 10) # 30 20 10
关键字实参
可以不按顺序传递, 形参按名字取值
fn1(a=10, b=20, c=30) # 10 20 30
fn1(c=30, b=20, a=10) # 10 20 30
位置实参和关键字实参混用
- 关键字实参必须出现在位置实参后
- 多个位置实参还是按照位置传参
- 关键字实参为没有从位置实参拿到值的形参传值,可以不用按照指定顺序
def fn2(a, b, c, d, e, f):
print(a, b, c, d, e, f)
fn2(10, 20, 30, e=100, f=500, d=200)
三、形参分类
(一).位置形参的范畴
1.位置形参(positional argument)
def fn(a, b, c):
print(a, b, c)
位置形参可以由位置实参与关键字实参来传值
fn(10, 20, 30)
fn(a=10, b=20, c=30)
2.默认形参
默认形参具有默认值,用=进行复制
def fn(a=10,b=20):
print(a, b)
默认形参可以由位置实参与关键字实参来传值,还可以不用传值(采用自身默认值)。
fn(n)
fn(20, 30)
fn(a=200, b=300)
fn(100) # 就给a传
fn(b=100) # 就给b传
位置形参与默认形参同时存在
默认形参必须在后
def fn1(a,b,c=10,d=20):
print(a, b, c, d)
位置形参必须传值,默认形参分情况传值
fn1(100, 200, d=1000)
3.可变长形参
只能由位置实参来传值
def fn(a, b=10, *args):
print(a, b)
print(args)
可变长形参会以元组形式接受位置形参与默认形参未接受完的所有传入的位置实参。
可变长形参只能接受位置实参的值,位置实参还必须在关键字实参前,导致默认形参只能由位置实参来传值。
fn(1, 20, 100, 200) # 1 20
(100, 200)
fn(100) # 100 10
()
整体赋值
def fn(*args):
print(args)
fn(1, 2, 3, 4, 5) # (1, 2, 3, 4, 5)
a = 'ab'
b = [1, 2]
c = (1, 2)
d = {1, 2}
fn(a) # ('ab', )
fn(b) # ([1, 2], )
fn(c) # ((1, 2), )
fn(d) # ({1, 2}, )
用a,b,c,d进行传值,如何得到(‘a’,‘b’),(1, 2)
*单列集合(保护字符串)将该变量进行 打散 传值 (本质传递的是地址)
fn(*a) # ('a', 'b')
fn(*b) # (1, 2)
fn(*c) # (1, 2)
fn(*d) # (1, 2)
打散
def fn1(*args):
print(args)
ls = [1, 2, 3, 4, 5]
fn1(ls) # (ls, )
fn1(*ls) # 将ls打散为1,2,3,4,5再进行传值=>(1,2,3,4,5)
(二).关键字形参的范畴
1.关键字形参
def tt(a, b=10, *, c, d=10, e):
print(a, b, c, d, e)
*为分割线,可以有变量名 *args, 也可以只用来做分隔
a:位置
b:默认
c,e:无值关键字形参
d:有值关键字形参
注:
a和b有先后顺序
c,d, e无先后顺序
关键字形参必须由关键字实参来传值, 出现在*后的都是关键字形参
def fn(*, a, b=10, c):
print(a, b, c)
#fn(10, 20, 30) # 错误:TypeError: fn() takes 0 positional arguments but 3 were given
fn(b=300, c=100, a=200)
2.可变长关键字形参
用来接收没有被关键字形参接收完的关键字形参,也只能由关键字实参来传值,用字典来存放数据。
def fn(*, a, b=20, c, **kwargs):
print(a, b)
print(kwargs)
fn(d=40, e=50, a=10, c=30) # 10 20
{'d': 40, 'e': 50}
整体赋值
dic = {'name': 'Owen', 'age': 18}
def fn1(**kwargs):
print(kwargs)
fn1(**dic) # {'name': 'Owen', 'age': 18}
dd = {
'k1': [1, 2, 3, 4, 5],
'k2': {"name":"Bob"}
}
fn1(**dd) # {'k1': [1, 2, 3, 4, 5], 'k2': {'name': 'Bob'}}
四、参数总结
def fn(a, b=10, *args, d, f=20, **kwargs):
print(a)
print(b)
print(args)
print(d)
print(f)
print(kwargs)
有位置实参传值: args和kwargs如果都能接收到值:
b必须传值且只能用位置实参传值,f可以不用传值
fn(1,2,3,4,d=5,g=6,k=7) # 1
2
(3, 4)
5
20
{'g': 6, 'k': 7}
全部用关键字实参传值
fn(x=100,y=200,d=300,b=400,a=500) # 500
400
()
300
20
{'x': 100, 'y': 200}
1.位置形参与默认形参: 能用 位置实参 关键字实参 传值
2.可变长位置形参:只能 位置实参 传值
3.所有关键字形参:只能 关键字实参 传值