您现在的位置: 365建站网 > 365文章 > Python 中 ** 是什么意思?幂运算、字典解包与 kwargs 三种用法

Python 中 ** 是什么意思?幂运算、字典解包与 kwargs 三种用法

文章来源:365jz.com 点击数:59 更新时间:2025-01-18 03:59

Python 里的 ** 出现在三种完全不同的语境下:幂运算符、字典解包(关键字参数),以及函数定义中的 **kwargs 可变关键字参数收集。三者共用同一符号,初学者很容易混。本文把三类用法、优先级规则与常见报错一次讲清。

python中**是什么意思

一、作为幂运算符(算术用途)

2 ** 10          # 1024
2 ** 0.5         # 1.4142135623730951(等价于开平方)
4 ** -1          # 0.25(负指数=取倒数)
2 ** 3 ** 2      # 512 —— 右结合,先算 3**2=9,再算 2**9

关键规则:** 是右结合(2**3**2 == 2**(3**2)),这与多数运算符不同。另一个易错点是与负号的优先级:

-2 ** 2          # -4,因为等价于 -(2**2)
(-2) ** 2        # 4

此外,2 ** float('inf') 会报错或返回 inf;0 ** -1 抛 ZeroDivisionError。整数幂在超大数时会占大量内存,做哈希或加密运算时应使用内置三参形式 pow(base, exp, mod)——它按模幂计算,远比 (base ** exp) % mod 高效。

二、作为字典解包(调用函数时)

在函数调用位置,**dict 把字典展开成关键字参数:

def create_user(name, age, city="未知"):
    return f"{name}-{age}-{city}"

cfg = {“name”: “张三”, “age”: 20}
create_user(**cfg) # 等价 create_user(name=“张三”, age=20)

合并后覆盖默认值

create_user(**cfg, city=“北京”)

限制与坑:

  • 字典的键必须是字符串(或合法标识符),否则报 TypeError: keywords must be strings。
  • 键与形参名不匹配 → TypeError: got an unexpected keyword argument。
  • 同一参数被传两次(显式 + 解包)→ got multiple values for argument。
  • 参数顺序:f(*args, **kwargs),*args 必须在 **kwargs 之前。

三、在函数定义中收集关键字参数(**kwargs)

def log(**kwargs):
    for k, v in kwargs.items():
        print(k, "=", v)

log(user=“abc”, level=3) # kwargs 是普通 dict

def make(*args, title, **meta): # 仅关键字参数 + 收集
return title, meta

定义侧的 **kwargs 让函数接收任意多个命名参数,常用于配置类接口、装饰器透传参数、以及封装第三方库。搭配规则:def f(位置参数, *args, 仅关键字参数, **kwargs)——顺序固定不能随意调换。

装饰器里最常见的透传写法:

import functools

def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(“before”)
return func(*args, **kwargs)
return wrapper

四、其他两个易混写法

  • *args(单星号):收集位置参数为元组;在调用处则是可迭代对象解包(f(*[1,2,3]))。
  • a, *b = [1,2,3]:星号在赋值左侧表示“收集剩余”,b == [2,3]。
  • Python 3.5+ 的 {**d1, **d2} 与 [*l1, *l2] 用于字面量合并;重复键后者覆盖前者,不报错,合并配置时要留意。

五、性能与安全提醒

  1. 2 ** 1000000 这类超大整数幂会耗尽内存并阻塞进程,服务代码里对指数做上限校验。
  2. 不要把外部输入直接当 **kwargs 展开传给敏感函数(如 subprocess.run(**user_input)),这可能构造出 shell=True 之类的危险参数。参数白名单是必须的。

六、常见问题 FAQ

问:pow(x, y) 和 x ** y 有区别吗?
答:两者等价;但 pow 支持第三参数取模,三参形式比先幂再取模快得多。

问:** 与位运算无关吗?
答:无关。Python 中没有“a ** b”作按位运算的用法;位运算用 & | ^ ~ << >>。其他语言(如 C# 的 ^)差异较大,注意别混。

问:解包时报 type object argument after ** must be a mapping?
答:** 后必须接映射(dict 类),传了列表/元组就会报这句;列表要用单星号 *。

记忆:出现在数字之间→幂(右结合,注意 -2**2==-4);出现在函数调用括号里→字典展开为关键字参数;出现在函数定义的形参位→收集关键字参数成 dict。三参 pow(a,b,m) 做模幂,比 ** 快且省内存。

生产内容,同时打通搜索引擎(SEO)与AI搜索引擎(GEO)流量入口的软件! 点击进入365建站器 »