• Python学习基础笔记十四——函数参数


    函数参数这块在前面的博客中没有展开,现在专门整理出来:

    1、参数的数量:

    1)没有参数:就是定义函数和调用函数的括号中都不写内容。

    2)有一个参数:可以是任何数据类型。

    3)有多个参数:例如位置参数。

    2、位置参数:

    概念:按照从左到右的顺序依次定义的参数,就称之为位置参数。

    位置形参:在定义函数阶段,按照从左到右的顺序直接定义的“变量名”。必须被传值、多一个不行、少一个也不行。

    位置实参:在函数调用阶段,按照从左到右的顺序依次传入的值。

    例1:

    1. def my_sum(a, b): # 位置形参
    2. res = a + b
    3. return res
    4. ret = my_sum(1, 2) # 位置实参
    5. print(ret)

    3、关键字参数:

    关键字实参:在函数调用阶段, 按照key=value的形式传入的值。就是指名道姓地给某个形参传值,可以完全不参照顺序。

    例2:

    1. def my_sum(a, b):
    2. res = a + b
    3. print('a: ', a)
    4. print('b: ', b)
    5. return res
    6. ret = my_sum(b=1, a=2)
    7. print(ret)

    4、默认参数(默认形参): 在定义函数阶段,就已经被赋值的形参,称之为默认参数。在定义阶段,就被赋值,意味着在调用阶段就不用再为其赋值,也就是可以不传。

    注意:所有位置参数必须出现在默认参数前,包括函数定义和调用。

    例3:

    1. def my_sum(a, b=7): # b是默认参数,有默认值7
    2. res = a + b
    3. print('a: ', a)
    4. print('b: ', b)
    5. return res
    6. ret = my_sum(1) # 调用时,就不用再为b赋值了
    7. print(ret)

     

    1. def overScoreStudent(studentScoreList, score):
    2. count = 0
    3. for ss in studentScoreList:
    4. if ss >= score:
    5. count += 1
    6. return count
    7. ssList = [87, 60, 50, 90, 34, 78, 82, 80]
    8. ret = overScoreStudent(ssList, 60)
    9. print(ret)

    在调用这个函数的时候,大部分的时候,都是统计超过及格分数线60的人数。

    那这个场景,我们完全可以将这个参数设置为默认参数。可以在定义函数的时候,第二个参数通常都加上默认值。

    1. def overScoreStudent(studentScoreList, score=60):
    2. count = 0
    3. for ss in studentScoreList:
    4. if ss >= score:
    5. count += 1
    6. return count
    7. ssList = [87, 60, 50, 90, 34, 78, 82, 80]
    8. ret = overScoreStudent(ssList, 60)
    9. print(ret)

    默认形参,也就是缺省值。 

    1. def overScoreStudent(studentScoreList, score=60):
    2. count = 0
    3. for ss in studentScoreList:
    4. if ss >= score:
    5. count += 1
    6. return count
    7. ssList = [87, 60, 50, 90, 34, 78, 82, 80]
    8. ret = overScoreStudent(ssList)
    9. print(ret)
    10. ret2 = overScoreStudent(ssList, 80)
    11. print(ret2)

    5、位置形参和默认参数(默认形参)可以混合使用:

    1、规则:位置形参必须位于默认形参的左边,但关键字参数之间是不存在先后顺序的。

    例4:

    1. def my_sum(a=7, b): # 现在我将默认参数放在位置参数的前面,我们看看有什么报错?
    2. res = a + b
    3. print('a: ', a)
    4. print('b: ', b)
    5. return res
    6. ret = my_sum(1)
    7. print(ret)

    结果截图:

    我们看到这个语法错误的意思:非默认参数跟在默认参数之后。也就是说位置参数是在默认参数之后了,更进一步说默认参数写在位置参数前面了。

    6、默认参数的值是在函数定义阶段赋值的,准确地说被赋予的是值的内存地址。

    例5:

    1. a = 7
    2. def func(x, y=a): # y 赋予的是7的内存地址
    3. print(x, y)
    4. a = 8
    5. func(1)

    结果:

    例6:

    1. a = [1, 3]
    2. def func(x, y=a): # y 被赋予[1, 3]的内存地址
    3. print(x, y)
    4. a.append(9)
    5. func(1)

     结果:

    7、默认值可以被指定为任意数据类型,但是最好不要使用可变类型,函数最理想的状态:函数的调用只跟函数本身有关系,不受外界代码的影响。

    例7:

    1. def func(x, y, z, l=None):
    2. if l is None:
    3. l = []
    4. l.append(x)
    5. l.append(y)
    6. l.append(z)
    7. print(l)
    8. func(1, 2, 3)
    9. func(11, 22, 33)
    10. list_1 = [111, 222]
    11. func(1, 2, 3, list_1)

    8、可变参数:

    定义函数的时候,我们不确定调用的时候会传递多少个参数(不传参也可以),此时,可用包裹packing位置参数或者包裹关键字参数,来进行参数传递,会显得非常方便。

    8.1 包裹位置传递:

    1. def my_sum(*args):
    2. sum = 0
    3. for i in args:
    4. sum = sum + i
    5. return sum
    6. print(my_sum(1, 2))
    7. print(my_sum(1, 2, 3))
    8. print(my_sum(1, 2, 3, 4))

    结果:

    我们传递的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包位置传递。

    如果将def my_sum(*args) 换成 def my_sum(*a) ,也是可以的,使用a来代替args。

    之所以叫args,这种一种习惯:

    packing包裹位置传递。元组(tuple的概念。)

    我们再看一个例子:

    1. def func(*args): # 站在形参的角度上,给变量加上*,就是组合传来的值。
    2. print(args)
    3. func(1, 2, 3, 4, 5)
    4. l = [1, 2, 3, 4, 5]
    5. func(*l) #站在实参的角度上,给一个序列加上*, 就是将这个序列按照顺序打散。

    注意:这段代码中的两个星号的作用,有“组合”和“打散”的作用。

    8.2 包裹关键字传递:

    1. def func(**kwargs):
    2. print(kwargs)
    3. print(func(a=1))
    4. print(func(a=1, b=2, c=3))

    kargs是一个字典(dict),搜集所有关键字参数。

    那么可以将两者结合起来:

    1. def func(*args, **kwargs):
    2. print(args, kwargs)
    3. print(func(1, 2, 3, 4 = 'good', 5 = 'best')

    前面是包裹位置参数,后面是包裹关键字参数。

    我们再看一个例子:

    1. def func(**kwargs):
    2. print(kwargs)
    3. func(a=1, b=2)
    4. d = {'a': 1, 'b': 2}
    5. print(func(**d))

    看看这个两个星号**的作用。也是“组合”和“打散”的作用。

    9、解包裹参数:

    *args和**kwargs, 也可以在函数调用的时候使用,称之为解包(unpacking)。(解包、打散的意思。)

    9.1 在传递元组的时候,让元组的每一个元素对应一个位置参数:

    1. def print_hello(name, sex):
    2. print(name, sex)
    3. args = ('tanggu', '男')
    4. print_hello(*args)

    解包的概念。

    2、在传递字典的时候,让字典的每个键值对作为一个关键字参数传递给函数。

    1. def print_hello(**kwargs):
    2. print(kargs)
    3. kwargs = {'name': 'tanggu', 'sex': u'男'}
    4. print_hello(**kwargs)

    解包打散的意思。

    10、位置参数、默认参数和可变参数的混合使用:

    10.1 规则:先位置参数、*args, 默认参数、**kwargs。

    11、函数的注释:

    11.1 可以给代码加行注释;

    11.2 使用三引号,里面写函数的功能、参数说明和返回值说明。我们看下一个函数的注释:

     这是一个非常标准的函数注释。

    2023年10月13日:

    重新温习一遍这篇参数的博客文章,后面的包裹(packing)和解包打散的概念还是讲得非常透彻的。

  • 相关阅读:
    C++笔记2(内存分区模型,引用)
    拿捏大厂面试,2022最新版的Java面试突击班手册
    Jmeter正则提取数据
    老卫带你学---leetcode刷题(96. 不同的二叉搜索树)
    Fiddler抓包使用教程
    springboot实现支付宝支付功能
    C标准库部分
    java计算机毕业设计计算机组成原理教学演示软件源码+数据库+系统+lw文档+mybatis+运行部署
    Linux二进制方式安装mysql8
    linux网络常用命令
  • 原文地址:https://blog.csdn.net/chang_chunhua/article/details/128062917