Python * and **到底是什么呢?(多值参数)

本文深入讲解了Python中多值参数的使用方法,包括如何通过*args接收元组参数和通过**kwargs接收字典参数,以及如何在函数中利用这些参数进行高效的数据处理。同时,文章还提供了实际案例,如计算任意多个数字的和,展示了多值参数在函数设计中的灵活性和实用性。

多值参数

定义支持多值参数的函数

  • 有时可能需要 一个函数 能够处理的参数 个数 是不确定的,这个时候,就可以使用 多值参数

  • python 中有 两种 多值参数:

    • 参数名前增加 一个 * 可以接收 元组
    • 参数名前增加 两个 * 可以接收 字典
  • 一般在给多值参数命名时,习惯使用以下两个名字

    • *args —— 存放 元组 参数,前面有一个 *
    • **kwargs —— 存放 字典 参数,前面有两个 *
  • argsarguments 的缩写,有变量的含义

  • kwkeyword 的缩写,kwargs 可以记忆 键值对参数

def demo(num, *args, **kwargs):

    print(num)
    print(args)
    print(kwargs)


demo(1, 2, 3, 4, 5, name="小明", age=18, gender=True)

提示:多值参数 的应用会经常出现在网络上一些大牛开发的框架中,知道多值参数,有利于我们能够读懂大牛的代码

多值参数案例 —— 计算任意多个数字的和

需求

  1. 定义一个函数 sum_numbers,可以接收的 任意多个整数
  2. 功能要求:将传递的 所有数字累加 并且返回累加结果
def sum_numbers(*args):

    num = 0
    # 遍历 args 元组顺序求和
    for n in args:
        num += n

    return num

print(sum_numbers(1, 2, 3))

元组和字典的拆包

  • 在调用带有多值参数的函数时,如果希望:
    • 将一个 元组变量,直接传递给 args
    • 将一个 字典变量,直接传递给 kwargs
  • 就可以使用 拆包,简化参数的传递,拆包 的方式是:
    • 元组变量前,增加 一个 *
    • 字典变量前,增加 两个 *
def demo(*args, **kwargs):

    print(args)
    print(kwargs)


# 需要将一个元组变量/字典变量传递给函数对应的参数
gl_nums = (1, 2, 3)
gl_xiaoming = {"name": "小明", "age": 18}

# 会把 num_tuple 和 xiaoming 作为元组传递个 args
# demo(gl_nums, gl_xiaoming)
demo(*gl_nums, **gl_xiaoming)

<think>我们正在讨论Python中变量名前加双星号(**)的含义和用法。根据提供的引用资料,可以总结出以下几点:1.**在函数定义中作为形参**:在函数定义时,使用`**kwargs`表示该函数可以接收任意数量的关键字参数。这些参数会被打包成一个字典(dictionary),其中键是参数名,值是参数值。例如:```pythondefexample(**kwargs):forkey,valueinkwargs.items():print(f"{key}:{value}")example(name="Alice",age=25)#输出:name:Alice,age:25```2.**在函数调用中作为实参**:在函数调用时,使用`**字典变量`可以将一个字典解包成关键字参数传递给函数。这要求字典的键必须是字符串,且与函数定义的形参名一致。例如:```pythondeffunc(a,b,c):print(a,b,c)args_dict={'a':1,'b':2,'c':3}func(**args_dict)#相当于func(a=1,b=2,c=3)```3.**注意点**:在函数定义时,`**kwargs`必须放在所有形参的最后。而在函数调用时,使用`**`解包字典时,字典的键必须与函数的形参名称匹配,否则会引发`TypeError`。4.**与`*`的区别**:单星号`*`用于处理非关键字参数,在函数定义中收集位置参数为元组,在函数调用中解包序列(列表、元组等)为位置参数。5.**不能用于数值运算和序列解包**:与单星号`*`不同,双星号`**`在数值运算中表示幂运算(如`2**3`结果为8),但在序列解包中,只有单星号`*`可用于解包序列,双星号`**`只用于字典(关键字参数)的解包和打包。综上所述,变量名前加`**`主要用于函数定义时收集关键字参数(打包成字典)和函数调用时解包字典为关键字参数。§§相关问题§§1.Python中单星号(*)和双星号(**)在函数参数传递中有哪些区别?2.如何在同一个函数中同时使用位置参数、默认参数、可变位置参数和可变关键字参数?3.在函数调用时使用**解包字典,如果字典中包含函数不接受的参数名会发生什么?4.除了函数参数传递,Python中双星号(**)还有哪些其他用途?</think>### Python中变量名前加双星号(**)的含义与用法 在Python中,变量名前加双星号(**)主要用于**函数参数传递**场景,可分为两种核心用法: #### 1. 函数定义时作为形参(收集关键字参数) 在函数声明中,`**变量名`用于收集所有未匹配的**关键字参数(key=value形式)**,将其打包成字典: ```python def user_profile(**kwargs): for key, value in kwargs.items(): print(f"{key}: {value}") user_profile(name="Alice", age=30, occupation="Engineer") # 输出: # name: Alice # age: 30 # occupation: Engineer ``` 此时`kwargs`是一个字典:`{'name': 'Alice', 'age': 30, 'occupation': 'Engineer'}`[^3][^5]。 #### 2. 函数调用时作为实参(解包字典) 在函数调用时,`**字典变量`将字典解包为**关键字参数**: ```python def connect_db(host, port, user): print(f"Connecting to {user}@{host}:{port}") config = {"host": "db.example.com", "port": 5432, "user": "admin"} connect_db(**config) # 等价于 connect_db(host="db.example.com", port=5432, user="admin") ``` 字典键必须与函数形参名完全匹配,否则引发`TypeError`[^4][^5]。 --- ### ⚠️ 关键注意事项 1. **字典键必须是字符串**:解包时字典键必须与目标函数的形参名称一致 ```python # 错误示例(键名错误) params = {"hostname": "server.com", "port": 8080} # 键应为"host"而非"hostname" connect_db(**params) # TypeError ``` 2. **不能与位置参数混用**:在函数定义时,`**kwargs`必须是最后一个参数 ```python # 正确顺序 def valid(a, b=10, *args, **kwargs): ... # 错误示例 def invalid(**kwargs, a): ... # SyntaxError ``` 3. **与单星号(*)的区别**: - `*args` 收集位置参数 → 元组 - `**kwargs` 收集关键字参数 → 字典 ```python def processor(*args, **kwargs): print("位置参数:", args) print("关键字参数:", kwargs) processor(1, 2, name="Bob") # 输出: # 位置参数: (1, 2) # 关键字参数: {'name': 'Bob'} ``` --- ### 典型应用场景 1. **函数包装器**:透明传递参数 ```python def debug_wrapper(func): def wrapper(*args, **kwargs): print(f"调用 {func.__name__}()") return func(*args, **kwargs) return wrapper ``` 2. **构造动态参数API**:如数据库查询 ```python def query_database(table, **filters): sql = f"SELECT * FROM {table} WHERE " conditions = [f"{key} = {value}" for key, value in filters.items()] sql += " AND ".join(conditions) return execute_sql(sql) ``` 3. **配置参数传递**:合并组配置 ```python base_config = {"timeout": 30, "retries": 3} custom_config = {"retries": 5, "verbose": True} final_config = {**base_config, **custom_config} # 合并字典 # 结果: {'timeout': 30, 'retries': 5, 'verbose': True} ``` > 注意:在非函数参数的上下文(如数值计算)中,`**`表示幂运算(如`2**3=8`)[^1],这与参数解包无关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值