• 2022年最新Python大数据之Python基础【七】参数与管理系统


    1、不定长参数

    • 位置不定长参数(*args):多余的位置参数,可以被args接收,并且打包为一个元组,保存在args当中。
    # 不定长参数主要就是在定义函数时,不确定参数的个数时即可进行不定长参数的书写
    
    '''
    位置不定长参数的定义格式:
    def 参数名(*args):
        函数体
    '''
    
    
    # def func(*args):
    #     print(*args)  # 相当于书写内容为  print(1,2,3)
    #
    #
    # func(1, 2, 3)
    # print(1, 2, 3)
    
    # args变量到底内部是什么样子的?
    # def func(*args):
    #     return args
    
    # 数据传入函数内部时,将传入的多个数据进行打包,转换为一个元组,被args接收.并且在函数体内部可以使用该元组参与运算
    # print(func(1, 2, 3))  # (1, 2, 3)
    
    
    # 案例:
    # 输入不确定数量的多个值,判断其中的最大值
    
    def max1(*args):
        max_num = args[0]  # 如果max_num = 0 这个时候我们所有值都没负的时候会判断出错
        for i in args:
            if i > max_num:
                max_num = i
        return max_num
    
    
    print(max1(1, 4, 5, 3, 6, 12, 3))
    
    # 如果输入的数值全部为负呢?
    print(max1(-1, -2, -5))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 关键字不定长参数(**kwargs):将多余的关键字 参数,打包为一个字典,保存在kwargs当中
    # 关键字不定长参数,可以接收多个未定义参数的关键字赋值
    
    '''
    关键字不定长参数的格式:
    def 函数名(**kwargs):
        函数体
    '''
    
    
    # TypeError: 'a' is an invalid keyword argument for print()
    # def func(**kwargs):
    #     print(**kwargs)  # 相当于给print输入了多个关键字参数  print(a=1, b=2, c=3)
    #
    #
    # func(a=1, b=2, c=3)
    
    # 使用**kwargs可以将关键字参数进行传递
    # def func(**kwargs):
    #     print(1, 2, **kwargs)  # 相当于print(1, 2, sep='&', end='a')
    #
    #
    # func(sep='&', end='a')
    
    # kwargs 内部到底是什么存储结构呢?
    def func(**kwargs):
        # kwargs 在从传参之后,会将实参位置的所有未定义参数的关键字参数转换为字典的键值对,保存在kwargs当中
        print(kwargs)  # {'a': 1, 'b': 2, 'c': 3}
    
    
    func(a=1, b=2, c=3)
    
    
    # 案例:
    # 使用创建一个函数可以保存学员的全部信息,并将其储存到字典当中
    
    def student_info(**kwargs):
        print(f'学员信息为:{kwargs}')
    
    
    student_info(name='xiaoming', age=18, gender='男')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    2、函数定义和调用时各类参数的排布顺序

    • 形参: 位置参数》》位置不定长参数》》缺省参数》》关键字不定长参数
    • 实参:顺序赋值》》关键字参数赋值
    • 在开发中除非有特殊需求,一般参数种类不超过三种,参数个数不超过5个,如果种类或数量太多,会造成我们开发中沟通成本加大
    # 在定义函数时:位置参数,缺省参数,位置不定长参数,关键字不定长参数  到底在定义时怎么排列呢?
    # 调用函数时:顺序赋值, 关键字赋值  调用时的传参顺序是什么样的呢?
    
    
    # 定义函数时:形参
    
    # 位置参数和缺省参数的位置关系:
    # def func1(a, b, c=10):
    #     print(a)
    #     print(b)
    #     print(c)
    # 缺省参数c 能否放到a,b之前或之间
    # SyntaxError: non-default argument follows default argument
    # 有默认值的参数只能放到没有默认值的参数之后,不能前置
    # def func1(c=10,a, b ):
    #     print(a)
    #     print(b)
    #     print(c)
    #
    # # 赋值时可以不给c传参因为其有默认值
    # func1(1, 2)
    
    # 结论: 在定义函数时,位置参数在缺省参数之前
    
    # 位置参数,缺省参数,位置不定长参数之间的位置关系
    # 顺序赋值多个参数,位置参数优先接收,然后缺省参数接收数据,多余的参数被args以元组形式打包接收
    # 思考:为什么要设置缺省参数呢?  一般情况下,缺省参数是不进行赋值的,因为绝大多数情况下都会赋默认值,极少情况下会使用关键字参数赋值
    # 如果放到*args之前,是不是每次给*args赋值,都要给缺省参数赋值,所以不是很方便
    # 综上考虑,我们决定将缺省参数放到*args之后
    
    # def func2(a, b, c=10, *args):
    #     print(a)
    #     print(b)
    #     print(c)
    #     print(args)
    # 传值逻辑如下:1.先给位置参数赋值 2.多余的未接收数据,被args打包为一个元组进行接收  3.缺省参数一般情况下不赋值,如果需要赋值,使用关键字参数赋值
    # 在官方文档或者系统模块中,都是这种顺序书写的
    # def func2(a, b, *args, c=10):
    #     print(a)
    #     print(b)
    #     print(c)
    #     print(args)
    #
    #
    # func2(1, 2, 3, 4, 5)
    
    
    # 结论:在定义函数时,先写位置参数,再写位置不定长参数,最后写缺省参数
    
    
    # 位置参数,缺省参数,位置不定长参数,关键字不定长参数之间的位置关系
    
    # def func2(a, b, *args, c=10, **kwargs):
    #     print(a)
    #     print(b)
    #     print(c)
    #     print(args)
    #     print(kwargs)
    #
    #
    # func2(1, 23, 4, 5, 3, 2, c=1, name='xiaoming', age=18)
    
    # 思考:**kwargs可不可以往前放
    # **kwargs只能放到最后,否则会报错
    
    # 结论:形参排布顺序为:位置参数>>位置不定长参数>>缺省参数>>关键字不定长参数
    
    
    # 调用函数时:实参
    
    def sum1(a, b):
        print(a + b)
    
    # SyntaxError: positional argument follows keyword argument
    # 顺序赋值,不能在关键字赋值之后
    # sum1(a=1, 2)
    
    # 结论,调用参数时,先使用顺序赋值,后使用关键字赋值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    3、组包和拆包

    • 组包:将多个数据,组合为一个容器类型,进行使用或变量保存
    • 拆包:将一个容器类型,进行拆分,其中的每一个元组赋值给其他的变量
    # 组包:就是讲多个值进行组合,打包为一个容器类型的过程
    # 拆包:就是讲一个容器类型,拆分成多个数据,分别赋值给多个变量的过程
    
    # 组包
    def func1():
        return 1, 2, 3, 4
    
    
    # func1返回了多个数据,Python自动将其打包为一个元组,这个过程就是组包
    print(func1())  # (1, 2, 3, 4)
    # 将多个数据打包整合为一个容器,赋值给变量,这个就是组包过程
    a = 1, 2, 3, 4
    print(a)
    
    # 拆包(解包)
    # 将等号右侧的列表,拆分为四个数据元素,分别赋值给a,b,c,d这个过程就是拆包
    a, b, c, d = [1, 2, 3, 4]
    print(a, b, c, d)
    
    # 之前我们在循环汇总用过拆包过程
    list1 = [1, 2, 3, 4]
    for index, value in enumerate(list1):
        print(index, value)
    
    dict1 = {'name': 'xiaoming', 'age': 18}
    for key, value in dict1.items():
        print(key, value)
    
    # 同时应用组包和拆包的案例
    
    a = 1
    b = 2
    # 需求:将a, b进行互换值
    # 这个互换过程,是先讲a,b的值提取出来,组包为一个元组,然后进行拆包,将元组内的两个数据分别赋值给,a,b变量
    a, b = b, a
    print(a, b)
    
    # 注意:字典可以拆包么?可以
    dict1 = {'a': 1, 'b': 2, 'c': 3}
    # 对字典进行拆包,得到的是字典的键
    char1, char2, char3 = dict1
    print(char1, char2, char3)
    
    # 集合可以拆包么?  可以
    # 对于集合进行拆包,没有任何问题,但是一般不会这样做,因为赋值顺序无法指定
    set1 = {'Tom', 'Bob', 'Rose'}
    a, b, c = set1
    print(a, b, c)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    4、引用

    • 数据的三个维度:值, 数据类型,唯一标识
      • 值: 数据计算时使用的值
      • 数据类型:数据的存储类型
      • 唯一标识:id ,也就是数据的内存地址的标识
    • 如果我们想要判断id 或者说唯一标识是否相等,我们使用is进行判断
    # 在Python中所有的数据分为三个维度: 值(判断==), 数据类型(int...float...), 唯一标识(id)
    
    # 值相等的数据,唯一标识和数据类型不一定相等
    bool1 = False
    int1 = 0
    # 0 和False的值相等
    print(bool1 == int1)  # True
    # 数据类型不等
    print(type(bool1) == type(int1))  # False
    # 唯一标识不等
    # id 判断数据是否是同一内存空间中的数据(同一内存空间中的数据必相等)
    print(id(bool1) == id(int1))  # False
    
    # 值和数据类型相等的,唯一标识不一定相等
    list1 = [1, 2, 3]
    list2 = [1, 2, 3]
    # list1 和list2 值相等
    print(list1 == list2)  # True
    # list1和list2 数据类型相等
    print(type(list1) == type(list2))  # True
    # list1 和list2 的唯一标识不等,也就是说,其所在的内存空间不一致
    print(id(list1) == id(list2))  # False
    
    # 唯一标识相等的, 值和数据类型必然相等
    # 在同一内存空间中只能储存同一个值
    str1 = 'abc'
    str2 = 'abc'
    # str1 和str2 的唯一标识相等
    print(id(str1) == id(str2))  # True
    # 数据类型相等
    print(type(str1) == type(str2))  # True
    # 数据值相等
    print(str1 == str2)  # True
    
    # 怎样判断id  唯一标识是否相等呢?  is关键字
    # 使用is可以判断是否为同一个内存空间中的数据
    print(list1 is list2)  # False
    print(str1 is str2)  # True
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    5、可变类型和不可变类型

    • 可变类型:内存空间中的数据可以被修改的数据类型
      • list set dict
    • 不可变数据类型:内存空间中的数据不可以被修改的数据类型
      • int float bool str tuple
    # 传参或者变量的传递是进行了值的传递 还是进行了引用地址的传递呢?
    
    list1 = [1, 2, 3, 4]
    list2 = [1, 2, 3, 4]
    #  id的值,我们称呼他为引用地址,list1 和list2 的引用地址不相同
    print(id(list1))  # 140652966394496
    print(id(list2))  # 140652968507776
    
    # 如果我向list1 中添加以数字,次数list2 中的值为多少? [1,2,3,4]
    list1.append(5)
    print(list1)
    print(list2)
    # 在list1中添加了数据,那list1的引用地址会发生变化么? 不会变化
    # list1,在使用append方法时,是将内存空间中的值进行了变化,没有修改内存地址,所以id值不变
    print(id(list1))  # 140652966394496
    
    # 如果我们使用list1 = list2,list1的引用地址发生变化了么?  变化
    list1 = list2
    # 在对list1赋值时,list2 将list1中的内存地址赋值给了list1,此时,list1和list2指向同一块内存空间
    print(id(list1))  # 140652968507776
    
    # 如果在list1中删除下标为1的元素,list2 会发生变化么? 会变化
    # list1  和list2 指向同一块内存空间,所以内存空间中的数据发生了改变,list1 和list2 均发生了变化
    list1.pop(1)
    print(list1)  # [1, 3, 4]
    print(list2)  # [1, 3, 4]
    
    # list 内存空间中的数据可以发生改变,这种数据类型我们称之为可变数据类型
    
    # 练习:
    list1 = [1, 2, 3, 4]
    list2 = [1, 2, 3, 4]
    list1 = [1, 2, 3, 4, 5]
    list2 = list1
    list1.pop(2)
    list1 + list2
    # list1 和list2  分别是多少
    print(list1)
    print(list2)
    
    # 练习:
    str1 = '12345'
    str2 = '12345'
    str1 = str2
    str1 = '123'
    str2 + str1
    print(str1)
    print(str2)
    
    str1 = '123'
    str2 = '123'
    print(id(str1))  # 140509725727984
    print(id(str2))  # 140509725727984
    
    # 我么可以修改str内部的元素么?  不可以
    # TypeError: 'str' object does not support item assignment
    # str1[0] = '2'
    # 既然内部元素不可修改,系统定义其值相同时,数据引用地址也相同
    
    # 我么称这种内存空间中的数据无法被修改的值为不可变数据类型
    
    
    # 结论:
    # 可变数据类型:  列表,集合,字典
    # 不可变数据类型: 字符串,元组,整型,浮点型,布尔型
    
    # 结论:在数据的传递过程中,是引用传递,不是值的传递
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    6、引用当做参数传递

    • 在函数传参过程中,变量会以引用的形式进行传参,也就是说我们的变量或参数传递是引用传递,不是值传递
      • 如果参数是可变数据类型,那么在函数内修改其引用地址指向空间内的数据,外部数据同时发生变化
      • 如果参数是不可变数据类型,其实也是引用传递,只不过引用地址指向的数据空间中的数据无法被修改
    # 将数字1所在空间的引用地址赋值给了a
    # a = 1
    # 将a所保存的引用你地址给了b
    # b = a
    
    
    def func(num_list):
        print(id(num_list))  # 140490414045760
        num_list.append(2)
        return num_list
    
    
    # 在进行参数传递时,是进行了地址传递,将list1 的引用地址传递给了num_list,num_list 修改内存空间中的数据时,list1,也会发生变化
    list1 = [1, 2, 3, 4]
    
    
    # print(id(list1))  # 140490414045760
    # print(func(list1))
    # print(list1)
    
    def func2(num_list):
        print(id(num_list))  # 140326362233472
        # 无论什么情况下,使用=赋值运算,就是讲等号右侧数据的引用地址,赋值给等号左侧的变量
        num_list = [1, 2, 3, 4, 5]
        print(id(num_list))  # 140466340833664
        return num_list
    
    
    print(id(list1))  # 140326362233472
    print(func2(list1))  # [1, 2, 3, 4, 5]
    print(list1)  # [1, 2, 3, 4]
    
    
    # 不可变数据类型
    def func1(char1):
        print(id(char1))  # 140228523715632
        # 不可变数据类型,在进行参数传递时,也是引用传递,但是他无法修改原有数据空间内的数据,如果想要修改只能改变引用地址,重新赋值(只有=才有改变引用的功能)
        char1.replace('a', 'b')
        return char1
    
    
    str1 = 'abc'
    print(id(str1))  # 140228523715632
    print(func1(str1))  # abc
    print(str1)  # abc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    后记

    📢博客主页:https://manor.blog.csdn.net

    📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
    📢本文由 Maynor 原创,首发于 CSDN博客🙉
    📢不能老盯着手机屏幕,要不时地抬起头,看看老板的位置⭐
    📢专栏持续更新,欢迎订阅:https://blog.csdn.net/xianyu120/category_11947788.html

  • 相关阅读:
    医疗软件制造商如何实施静态分析,满足 FDA 医疗器械网络安全验证
    1.7-32:行程长度编码
    18.透彻理解死锁
    Postgres数据备份与恢复
    通过 Azure 日志分析加强云安全
    git 删除大文件记录解决拉取代码超时问题
    Linux - make与makefile
    [LitCTF 2023]导弹迷踪
    MySQL 更新表的记录
    VSCode里使用条件断点(基于GDB)
  • 原文地址:https://blog.csdn.net/xianyu120/article/details/126596839