# 一、形参与实参介绍
# 形参:在定义函数阶段定义的参数称之为形式参数,简称形参,相当于变量名
def func(x,y):
print(x,y)
# 实参:再调用函数阶段传入的值称之为实际参数,简称实参,相当于变量值
func(1,2) # 1 2
# 形参与实参的关系:
# 1、在调用阶段,实参会绑定给形参
# 2、这种绑定关系只能在函数体内使用
# 3、实参与形参的绑定关系在函数调用时生效,函数调用结束后解除绑定关系
# 实参是传入的值,但是值可以是以下形式
# 形式一:
func(1,2) # 1 2
# 形式二:
a=1
b=2
func(a,b) # 1 2
# 形式三:
func(int('1'),2) # 1 2
func(func(1,2),func(1,2)) # None None
# 二、形参与实参的具体介绍
# 1、位置参数:按照从左到右的顺序依次定义的参数称之为位置参数
# 位置形参:在函数定义阶段,按照从走到右的顺序直接定义的"变量名"
# 特点:必须被传值,多一个不行,少一个也不行
def func(x,y):
print(x,y)
# 位置实参:在函数调用阶段,按照从左到右的顺序依次传入的值
# 特点:按照顺序与形参一一对应
func(3,1) # 3 1
# 2、关键字参数(实参)
# 关键字实参:在函数调用阶段,按照key=value的形式传入的值
# 特点:指名道姓的给某个参数传值,可以安全不按照顺序传值
func(y=3,x=1) # 1 3
# 强调:混合使用
# 1⃣️、位置实参必须放在关键字实参前面
func(1,y=2) # 1 2
# func(x=1,2) # SyntaxError: positional argument follows keyword argument
# func(y=1,2) # SyntaxError: positional argument follows keyword argument
# 2⃣️、不能为同一个形参传入重复传值
# func(1,y=2,x=3) # TypeError: func() got multiple values for argument 'x'
# 3、默认参数
# 默认形参:在定义函数阶段,就已经被赋值的形参,称之为默认参数
# 特点:在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值
def func(x,y=3):
print(x,y)
func(1) # 1 3
func(1,10) # 1 10
# 位置形参与默认形参的混合使用,强调:
# 1、位置形参必须在默认形参的左边
# def dunc(y=2,x): # SyntaxError: non-default argument follows default argument
# pass
# 2、默认参数的值是在函数定义阶段被赋值的
# 示范1:
m=2
def func(x,y=m): # y指向的是常量2的内存地址
print(x,y)
m=33333
func(1) # 1 2 因为默认参数的值是在函数定义阶段被赋值的为
# 示范2:
m=[1111,]
def func(x,y=m): # y指向的是列表[1111,]的内存地址
print(x,y)
func(1.5) # 1.5 [1111]
m.append(3333)
func(1.5) # 1.5 [1111, 3333]
# 3、虽然默认值可以被指定为任意类型,但是不推荐使用可变类型。(因为如果是可变类型,输出要靠猜了,失去了默认的意义了)
# 不过可以写成下面的样子
def func(x,y,z,l=None):
if l is None:
l=[]
l.append(x)
l.append(y)
l.append(z)
print(l)
func(11,22,33) # [11, 22, 33]
func(11,22,33,[444,55,66]) # [444, 55, 66, 11, 22, 33]
# 4、可变长度的参数(*和**的用法)
# 可变长度指的是在调用函数时,传入的值(实参)的个数不固定,所以针对溢出的实参,必须有对应的形参
# 4.1、可变长度的位置参数
# 1⃣️、*形参名:用来接受溢出的闻之形参,溢出的位置实参会被*保存成元祖的格式赋值给紧跟其后的形参名
# 但是一般用 *args 表示可变形参
def func(x,y,*z): # z=(3,4,5,6,7)
print(x,y,z)
func(1,2,3,4,5,6,7) # 1 2 (3, 4, 5, 6, 7)
# 实现输入值累加
def leijia(*args):
result = 0
for num in args:
result+=num
return result
print(leijia(1,2,3,4,5,6,7,8,9)) # 45
print(leijia(1,2,3,4,5,6,7,8,9,)) # 45 这中形式也可以
# print(leijia(1,2,3,4,5,6,7,8,9,,,)) # SyntaxError: invalid syntax 这个就会报错
# 2⃣️、*还可以用在实参中,实参中带*,先将*后的值拆解称位置实参
def func(x,y,z):
print(x,y,z)
func(*[11,22,33]) # 11 22 33
# func(*[11,22,]) # TypeError: func() missing 1 required positional argument: 'z'
l=[11,22,33]
func(*l) # 11 22 33
# 3⃣️、形参和实参中都带*
def func(x,y,*args):
print(x,y,args)
func(1,2,[33,44,55]) # 1 2 ([33, 44, 55],) 注意是元组的形式给了args这个形参 所以args=([33, 44, 55],)
func(1,2,[33,44,55],[66,77]) # 1 2 ([33, 44, 55], [66, 77]) 注意是元组的形式给了args这个形参 所以args=([33, 44, 55], [66, 77])
func(1,2,*[33,44,55]) # 1 2 (33, 44, 55)
# 4.2、可变长度的关键字参数
# 1⃣️、**形参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典格式,然后赋值给紧跟其后的形参名
# **kwargs 一般用这个表示
def func(x,y,**kwargs):
print(x,y,kwargs)
# func(1,2,9,8,7,6,5,4) # TypeError: func() takes 2 positional arguments but 8 were given
func(1,2,a=9,b=8,c=6) # 1 2 {'a': 9, 'b': 8, 'c': 6}
func(1,2,a=9,b=8,c=6,) # 1 2 {'a': 9, 'b': 8, 'c': 6}
# 2⃣️、**还可以用在实参中,实参中带**,先将**后的值拆解称关键字实参
def func(x,y,z):
print(x,y,z)
# func(**[11,22,33]) # TypeError: func() argument after ** must be a mapping, not list
func(*{'x':0,'y':'1','z':2}) # x y z 拿的是字典的key
func(**{'x':0,'y':'1','z':2}) # 0 1 2 拿的是字典的value
func(1,*{'y':'1','z':2}) # 1 y z
func(1,**{'y':'1','z':2}) # 1 1 2
# func(**{'x':1,'a':1,'z':3}) # TypeError: func() got an unexpected keyword argument 'a' 因为形参中没有定义a
# 3⃣️、形参和实参中都带**
def func(x,y,**kwargs):
print(x,y,kwargs)
func(x=1,y=2,a=333,c=444) # 1 2 {'a': 333, 'c': 444}
# func(1,2,{'a':4},**{'b':5}) # TypeError: func() takes 2 positional arguments but 3 were given
func(1,2,**{'b':5}) # 1 2 {'b': 5}
func(1,2,**{'b':5,'z':999}) # 1 2 {'b': 5, 'z': 999}
# func(**{'b':5,'z':999}) # TypeError: func() missing 2 required positional arguments: 'x' and 'y'
func(**{'b':5,'z':999,'x':-1,'y':-22}) # -1 -22 {'b': 5, 'z': 999}
# 混用*与** : *args必须要在**kwargs之前
def func(*args,**kwargs):
print(args)
print(kwargs)
func(1,2,3,x=1,y=1,z='hello')
# (1, 2, 3)
# {'x': 1, 'y': 1, 'z': 'hello'}
# 应用场景
def index(x,y,z,bbb):
print("====> index : ",x,y,z,bbb)
def wrapper(*args,**kwargs):
index(args,kwargs)
# wrapper(1,2,{'z':3,'bbb':4}) # TypeError: index() missing 2 required positional arguments: 'z' and 'bbb'
# wrapper(1,2,**{'z':3,'bbb':4}) # TypeError: index() missing 2 required positional arguments: 'z' and 'bbb'
# wrapper(1,2,4,5) # TypeError: index() missing 2 required positional arguments: 'z' and 'bbb'
def index(x,y, z,bbb):
print("====> index : ",x,y,z,bbb)
def wrapper(*args,**kwargs):
print("args:",args," kwargs:",kwargs)
# index(args,kwargs) # TypeError: index() missing 2 required positional arguments: 'z' and 'bbb'
index(args,args,kwargs,kwargs) # ====> index : (1, 2) (1, 2) {'bbb': 4, 'z': 3} {'bbb': 4, 'z': 3}
wrapper(1,2,bbb=4,z=3) # TypeError: index() missing 2 required positional arguments: 'z' and 'bbb'
# wrapper(1,2,{'z':3},{'bbb':4}) # TypeError: index() missing 2 required positional arguments: 'z' and 'bbb'
# 5、命名关键字参数(了解)
# 命名关键字参数:在定义函数时,*后定义的参数,如下图所示,称之为命名关键字参数
# 特点:
# 命名关键字参数的实参必须按照key=value的形式传值
def func(x,y,*,a,b): # 其中 a,b称之为命名关键字参数
print(x,y,a,b)
# func(1,2,333,444) # TypeError: func() takes 2 positional arguments but 4 were given
func(1,2,b=444,a=333) # 1 2 333 444
def func(x,y,*,a=1111,b): # 其中 a,b称之为命名关键字参数; 注意⚠️ a并不是默认参数(默认参数必须写在位置参数后面),a,b称之为命名关键字参数,只不过a带有默认值
print(x,y,a,b)
# func(1,2,333,444) # TypeError: func() takes 2 positional arguments but 4 were given
func(1,2,b=444) # 1 2 1111 444
func(1,2,b=444,a=333) # 1 2 333 444
# 6、组合使用(了解) 没有应用场景
#参数位置顺序必须是: 位置形参、默认形参、*args、关键字形参、**kwargs
def func(a,b,c=333,*args,d=1,**kwargs):
print(a,b,c,args,d,kwargs)
func(1,2,5,6,7,{'x':1,'y':2}) # 1 2 5 (6, 7, {'x': 1, 'y': 2}) 1 {} # 强调下:*args用位置实参传值,**kwargs用关键字实参传值
func(1,2,d=8,x=1,y=3) # 1 2 333 () 8 {'x': 1, 'y': 3} # 强调下:*args用位置实参传值,**kwargs用关键字实参传值
# 小结:
# 函数调用常见形式:
def func(x,y):
print(x,y)
# 位置实参
func(1,2) # 1 2
# 关键字实参
func(x=1,y=3) # 1 3
# 位置+关键字实参
# func(y=1,3) # SyntaxError: positional argument follows keyword argument 语法错误:因为位置参数不能写在关键字参数后面
func(1,y=3) # 1 3
# 可变长度位置实参
# func(*'hello') # TypeError: func() takes 2 positional arguments but 5 were given 语法错误:因为拆解后的参数个数大于2
func(*'he') # h e
# 可变长度关键字实参
# func(**"hello") # TypeError: func() argument after ** must be a mapping, not str 语法错误:因为可变长度关键字实参必须是字典类型
# func(**{"a":1,"b":2}) # TypeError: func() got an unexpected keyword argument 'a' 语法错误:因为可变长度关键字实参的key必须是定义的形参
func(**{"x":333,"y":444}) # 333 444
# 可变长度位置实参+可变长度关键字实参
# func(*"q",**{"x":333,"y":444}) # TypeError: func() got multiple values for argument 'x' # 语法错误:因为位置形参x(和y)不能被重复赋值
func(*"q", **{"y": 333}) # q 333
Python基础27:函数的参数使用
最新推荐文章于 2022-06-16 20:37:28 发布