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

一、作为幂运算符(算术用途)
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]用于字面量合并;重复键后者覆盖前者,不报错,合并配置时要留意。
五、性能与安全提醒
2 ** 1000000这类超大整数幂会耗尽内存并阻塞进程,服务代码里对指数做上限校验。- 不要把外部输入直接当
**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建站器 »
