21天学习python编程_函数参数,理解 *args和**kwargs

主要内容:

  • 小目标:搞定函数参数与调用
  • 主要内容:函数参数,函数调用

如果看完这篇文章,你还是弄不明白函数参数;
你来找我,我保证不打你,我给你发100的大红包。

1. 函数定义

前面文章中,我们介绍过函数,这次我们再来详细介绍下

1.1 函数定义:

def funcname(args):
    pass
  • 函数调用:函数名+(), 例如,func()
  • 函数定义关键点:def,函数名,函数参数;
  • 函数默认返回值None,
  • 显示加返回值使用return

1.2 函数命名规则:

遵循:可读性好,可以通过函数名能了解函数功能;

  • 常用函数命名规范:
    1. 每个单词首字母大写,例如:GetValueByID
    2. 首字母小写,其余每个单词首字母大写:getValueById
    3. 单词与下换线组合,例如:get_value_by_id

具体命名规则可以根据公司规定。

2. 函数作用:

  • 封装,模块化
  • 代码复用

3. 函数参数与调用

函数可以带参数,也可以不带参数;不同参数函数,调用方式也不一样。

3.1 无参函数与调用

  • 无参函数:函数定义时候没有参数;
  • 应用场景:产生时间戳,产生随机数等
  • 示例:0~10000之间随机数
    import random
    #gerRandom():没有参数
    def getRandom():
        return random.randint(0,10000)
  • 调用过程:函数名+()
    import random
    #gerRandom():没有参数
    def getRandom():
        return random.randint(0,10000)
    print(getRandom())

    结果:9744

3.2 带参数函数

通俗理解,就是给函数加上参数
一个除法函数:

#除法函数,x,y两个参数
def myDiv(x, y):
        return x/y

x,y称为形参

  • 函数调用:
    直接看例子:
    #除法函数,x,y两个参数
    def myDiv(x, y):
        return x/y
    print(myDiv(10,2))

    结果:5.0

  • 函数调用注意点:

    1.参数一致性,参数数量与函数定义一直
    2.赋值顺序:按照前后顺序依次赋值,x=10,y=2

3.3 带默认参数函数

  • 函数定义,给参数加一个默认值,示例:
    #y的默认值1
    def mydiv(x, y=1):
        return x/y
  • 注意点:带默认值参数,必须放到不带默认值后面
    错误定义方式:
    def mydiv(y=1,x):
        return x/y

    报错:

    SyntaxError: non-default argument follows default argument
  • 函数调用:
    def mydiv(x, y=1):
        return x/y
    #x=2,y的默认值为1
    print(mydiv(2))
    #x=2,y=2,y=1无效
    print(mydiv(2,2))

    结果:2.0, 1.0

3.4 函数调用:关键字参数使用

  • 函数参数比较多,为了避免顺序出错,在调用函数时候,可以使用关键字参数:
    一个例子:
    def myDiv(x,y):
        return x/y
    #不用关键字参数
    print(myDiv(2,1))
    #关键字参数
    print(myDiv(y=10,x=2))
    #y使用关键字参数
    print(myDiv(5,y=2))

    结果:

    2.0
    0.2
    2.5
  • 错误使用方式:
    #错误方式,关键字参数必须放后面,
    myDiv(y = 5,2)
    myDiv(x=5, 2)
    #下面这种方式,函数认为传递两个参数x,所以错误
    myDic(2,x=4)

    以上就是函数基本定义与调用

4. 可变长参数

一些函数与方法中,使用下面方式定义函数:

def myfunc(x, *args, **kwargs): pass

问题:*args, **kwargs分别是什么?

4.1 可变长非关键字参数

  • *args:函数中的可变长非关键字参数

直接来看个例子:求和函数:

def mySum(x,y):
        return x+y
print(mySum(1,2))

结果:3

需求:mySum计算多个数值和,例如2个数,3个数,N个数,如何实现?
可以使用*args参数,重新定义mySum函数:

def mySum(x,y,*args):
        return x+y+sum(args)
#最少传2个参数
print(mySum(1,2))
#三个参数
print(mySum(1,2,3))
#5个参数
print(mySum(1,2,3,4,5))

结果:

3
6
15
  • 代码分析:

    mySum中*args作用:表示可变长非关键字参数;
    mySum(1,2,3,4,5)调用中,参数处理过程如下;
    x =1, y =2;
    其他参数通过*args处理,将3,4,5收集到一个元组中;

验证:

def mySum(x,y,*args):
    #输出args值与类型
    print('*args:', args, type(args))
    return x+y+sum(args)
#调用
mySum(1,2)
mySum(1,2,3,4)

结果:

*args: () <class 'tuple'>
*args: (3, 4) <class 'tuple'>

从输出结果中看到:

*args是一个元组
sum(args),对元组求和

4.2 函数调用中,mySum(1,2,args)中的\args什么意思?

先来看例子:

values = [1,2,3]
mySum(10,20, *values)
  • 问题:*values是什么意思?

    在函数调用中,mySum(10,20, *values)中的*values是将values打散,变成一个个数值,
    然后在重新收集到新元组中的过程。

案例:

def mySum(x,y,*args):
    print('*args:', args, type(args))
    return x+y+sum(args)
v1 = (3,4)
v2 = [5,6]
#*v1:将(3,4)->3,4,结果:mysum(1,2,4,5)
print(mySum(1,2, *v1))
#*v2:将[5,6]->5,6,结果:mysum(1,2,5,6)
print(mySum(1,2, *v2))

结果:

*args: (3, 4) <class 'tuple'>
10
*args: (5, 6) <class 'tuple'>
14

4.3 可变长关键字参数

可变长关键字参数使用场景比较多,例如多条件查询等;

一个例子:

def func(x,y,**kwargs):pass

问题:**kwargs什么意思?
可变长关键字参数,对比*args理解;

调用函数时,传入的关键字参数数量不定,需要使用:**kwargs;
示例:

def myfunc(sid, name, **kwargs):
    print(kwargs, type(kwargs))
#math,chinese->{math:100,chinese:80}
myfunc(1,'sun', math=100,chinese=80)
#math->{math:70}
myfunc(2,'li', math=70)

结果:

{'math': 100, 'chinese': 80} <class 'dict'>
{'math': 70} <class 'dict'>

可以看到:

kwargs为字典:
**kwargs:将math,chinese及对应值整理到一个字典中;

4.4 函数调用中:**kwargs什么意思?

直接看例子:

def myfunc(sid, name, **kwargs):
    print(kwargs, type(kwargs))
    #获取kwargs中的值
    print(kwargs.get('chinese'))

info = {'chinese':90}
#**info -> chinese=90
myfunc(1,'sun',**info)
#下面调用有问题
myfunc(1,'sun',info)

结果:

{'chinese': 90} <class 'dict'>
90
TypeError: myfunc() takes 2 positional arguments but 3 were given

函数调用中,myfunc(1,'sun',**info)分析:

**info将info打散,简单理解为将其变成关键字参数:chinese=90
myfunc再将其重新整理到字典kwargs中

到这里我们对可变长参数及调用过程有一定了解了。

4.5 函数定义参数顺序:

为了避免出错,顺序最好如下:

def func(形参,*args, 带默认值参数,**kwargs):pass

例1:

def func(x, y, *args, z=10, **kwargs):
    print(x,y,args, z, kwargs)
func(1,2,4,5,19, z = 20)
func(1,2,4,5,19, z = 20,t=10)

结果:

1 2 (4, 5, 19) 20 {}
1 2 (4, 5, 19) 20 {'t': 10}

例2:

def func(x, y, z=10, *args, **kwargs):
    print(x,y,args, z, kwargs)
func(1,2,4,5,19)
#z为带默认值形参,赋值中:z=4,与z=20冲突,所以有问题
func(1,2,4,5,19, z = 20,t=10)

结果:

1 2 (5, 19) 4 {}
TypeError: func() got multiple values for argument 'z'

总结:

  • 函数定义注意参数:无参数,形参,带默认值参数,可变长参数;
  • 函数调用:调用者传入参数与函数定义一致,并遵循Python函数语法规则。

猜你喜欢

转载自blog.51cto.com/huangyg/2512677