Python基础27:函数的参数使用

# 一、形参与实参介绍
# 形参:在定义函数阶段定义的参数称之为形式参数,简称形参,相当于变量名
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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值