• 彻底掌握Python中 * 号


    Python中的 *是一个特殊的符号,在其他编程语言中,它最广为人知的用途就是作为乘法运算的符号。
    而在Python中,它的用途远不止如此。

    本文总结了Python中*的所有用途,以供参考。

    1. 算术运算

    用来做算术运算几乎是所有编程语言采用的方法,
    在Python中,
    可作为乘法运算和指数运算。

    比如:

    a = 3
    b = 5
    print("乘法:3×5 = {}".format(a * b))
    print("指数:3的5次方 = {}".format(a**b))
    
    # 运行结果
    乘法:3×5 = 15
    指数:35次方 = 243
    

    2. 构造与解构

    除了基本的算术运算,*在Python中还可以用在数据结构的构造和解构中。

    2.1. 列表的构造

    如果要在一些数据中间的某个位置插入一个现有的列表,来构造一个新列表的话,
    大部分语言只能通过循环来实现。

    Python中的*,可以让我们用一行代码就实现。

    lst = [1, 2, 3]
    new_lst = [0, lst, 4, 5]
    print("不使用*号,构造后的列表:{}".format(new_lst))
    
    new_lst = [0, *lst, 4, 5]
    print("使用*号,构造后的列表:{}".format(new_lst))
    
    # 运行结果
    不使用*号,构造后的列表:[0, [1, 2, 3], 4, 5]
    使用*号,构造后的列表:[0, 1, 2, 3, 4, 5]
    

    使用*,可以自动将现有列表中的元素展开。

    2.2. 列表的解构

    简单来说,解构就是将列表中的元素分配给几个变量。
    比如下面的代码,利用*,可以迅速将一个列表中的元素分为3个部分:

    # 列表解构
    first, *lst, last = new_lst
    print("列表第一个元素:{}".format(first))
    print("列表中间元素:{}".format(lst))
    print("列表最后一个元素:{}".format(last))
    
    # 运行结果
    列表第一个元素:0
    列表中间元素:[1, 2, 3, 4]
    列表最后一个元素:5
    

    2.3. 字典的构造

    字典的构造是用 两个*号

    dict = {"name": "harry", "age": 40}
    new_dict = {"gender": "male", **dict}
    print("构造后的字典:{}".format(new_dict))
    
    # 运行结果
    构造后的字典:{'gender': 'male', 'name': 'harry', 'age': 40}
    

    这样,就把已有字典中的key/value展开到新的字典中去了。

    注意,字典类型的变量如果不加双*号,是会报错的,比如:

    new_dict = { "gender": "male", dict}
    # 这样写会报语法错误
    

    字典只有构造的方法,没有类似列表的解构方法。

    3. 函数参数

    *用在函数参数中,可以定义更加灵活的参数形式。

    3.1. 不定长参数

    不定长参数让函数更加灵活,比如 print函数的参数就是不定长的,传入几个参数,它就打印几个。
    再比如,我们构造一个求和的函数,希望可以对任意数量的整数求和,就可以用*来实现。

    # 求和函数
    def add(*numbers):
        sum = 0
        for number in numbers:
            sum += number
    
        return sum
    

    使用此函数时,可以传入任意数量的参数:

    # 可以传入任意数目的参数
    sum = add(1, 2, 3)
    print("1~3 求和:{}".format(sum))
    sum = add(1, 2, 3, 4)
    print("1~4 求和:{}".format(sum))
    
    # 运行结果
    1~3 求和:6
    1~4 求和:10
    

    当然,对于有 * 的参数,也可以传入列表变量作为参数,不过列表变量前要加 *

    lst = [1, 2, 3]
    sum = add(*lst)  # 变量 lst 前不加 *号 会报错
    print(sum)
    

    3.2. 不定长的关键字参数

    所谓关键字参数,就是传入参数的时候,不仅传入参数的值,还传入参数的名称。
    比如下面一个模拟改变对象属性的函数:

    def change(obj, **attrs):
        for key, val in attrs.items():
            obj[key] = val
    

    通过参数**attr,函数可以修改obj对象的任意属性。
    这样的好处是不用定义多个不同的函数来修改obj的不同属性。

    person = {"name": "harry", "age": 30, "gender": "male"}
    print("修改前:{}".format(person))
    
    # 调用方式
    change(person, age=40, name="jack")
    print("修改后:{}".format(person))
    
    # 运行结果
    修改前:{'name': 'harry', 'age': 30, 'gender': 'male'}
    修改后:{'name': 'jack', 'age': 40, 'gender': 'male'}
    

    4. 限制函数调用

    最后的这个*的用途比较罕见,如果你知道这个用途的话,我会对你很佩服。

    先定义一个示例函数:

    def self_introduce(name, age):
        print("大家好,我是 {}, 今年 {} 岁。".format(name, age))
    

    这个函数很简单,传入nameage两个参数,然后打印一段简单的自我介绍。

    Python中,我们可以用下面两种方式调用这个函数:

    # 方式一
    self_introduce("harry", 40)
    # 运行结果
    大家好,我是 harry, 今年 40 岁。
    
    # 方式二
    self_introduce(name="harry", age=40)
    # 运行结果
    大家好,我是 harry, 今年 40 岁。
    

    两种方式的效果是是一样的。
    方式一也可以叫做位置参数调用法;
    方式二也可以叫做关键字参数调用法。

    4.1. 只能用关键字参数方式调用

    如果我们想限制self_introduce只能用方式二(关键字参数)来调用,可以:

    # 函数的第一个参数用 * 号
    def self_introduce(*, name, age):
        print("大家好,我是 {}, 今年 {} 岁。".format(name, age))
    

    这样调用时,只能使用方式二了。

    # 这样调用会报错
    self_introduce("harry", 40)
    
    # 可以正常执行
    self_introduce(name="harry", age=40)
    

    4.2. 只能用位置参数方式调用

    如果想限制self_introduce只能用方式一(位置参数)来调用,可以:

    # 函数的最后一个参数用 / 号
    def self_introduce(name, age, /):
        print("大家好,我是 {}, 今年 {} 岁。".format(name, age))
    

    这样调用时,只能使用方式一了。

    # 可以正常执行
    self_introduce("harry", 40)
    
    # 这样调用会报错
    self_introduce(name="harry", age=40)
    
  • 相关阅读:
    数据结构预算法--链表(单链表,双向链表)
    【BurpSuite】插件学习之Log4shell
    MySQL8实现主从备份
    openwrt开发使用-arping
    MM32F0140 UART1 DMA Interrupt RX and TX (UART1 DMA中断接收和DMA中断发送数据)
    LeetCode 之 二分查找
    Docker两个容器互相请求接口
    「Verilog学习笔记」优先编码器电路①
    vue-element-admin项目部署 nginx动态代理 含Docker部署、 Jenkins构建
    44springboot摄影跟拍预定管理系统
  • 原文地址:https://www.cnblogs.com/wang_yb/p/17819180.html