LEEFEI571 发表于 2025-1-19 14:47:14

函数中解包参数的困惑

在看小甲鱼老师关于函数的课程中,其中一个例子是讲解包关键字参数的,例子如下:

定义关键字参数
kwargs = {'a':1,'b':2,'c':3,'d':4}

定义函数
def myfunc(a,b,c,d):
   return a,b,c,d

调用函数:
myfunc(**kwargs)

函数返回结果:
(1, 2, 3, 4)

此时输入a的话,反显结果1.

当我把函数的形参改为其他值的话,则会报错,情况如下:
def func2(w,x,y,z):
   return w,x,y,z

func2(**kwargs)
此处则会报错:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func2() got an unexpected keyword argument 'a'

我的困惑是如果在定义函数形参是不是a,b,c,d,而是其他形参的话,如w,x,y,z,为何程序报错?是不是定义函数的形参必须与关键字参数的键必须保持一致?麻烦大神指点,谢谢!

FishC 发表于 2025-1-19 14:47:24

你提到的情况确实触及了 Python 中的关键字参数解包机制。下面为你解答这个疑惑:

问题解答

当使用关键字参数解包(即 **kwargs)调用函数时,函数的形参名必须与关键字参数的键名相匹配。否则会报错。这是因为 Python 解包时,会将 `kwargs` 中的键和值依次匹配到函数的形参中。如果键名和形参名不一致,那么对应的值就无法成功传递,程序会抛出 `TypeError`。

在你的例子中:


[*] `kwargs = {'a': 1, 'b': 2, 'c': 3, 'd': 4}` 里的键名为 `a`、`b`、`c` 和 `d`。
[*] 函数 `myfunc(a, b, c, d)` 的形参名为 `a`、`b`、`c` 和 `d`,完全匹配,因此解包时不会出错,结果为 `(1, 2, 3, 4)`。
[*] 函数 `func2(w, x, y, z)` 的形参名为 `w`、`x`、`y` 和 `z`,与 `kwargs` 的键名不匹配。Python 无法将 `kwargs` 中的键解包绑定到形参,因此报错:“`TypeError: func2() got an unexpected keyword argument 'a'`”。


结论

是的,函数的形参名称必须与关键字参数解包时的键名保持一致,否则会报错。

如何修正代码?

如果你希望通过解包来调用函数,需要确保 `kwargs` 的键名与形参名一致。例如:


# 定义与 kwargs 键名一致的形参
def func2(a, b, c, d):
    return a, b, c, d

# 仍然可以解包成功
print(func2(**kwargs))# 输出: (1, 2, 3, 4)


或者,你也可以在构造 `kwargs` 时修改键名以匹配形参名:


# 修改 kwargs 的键名以匹配 func2 的形参名称
kwargs_2 = {'w': 1, 'x': 2, 'y': 3, 'z': 4}

# 调用 func2
def func2(w, x, y, z):
    return w, x, y, z

print(func2(**kwargs_2))# 输出: (1, 2, 3, 4)


通过以上方式,你可以成功避免报错。

希望解答对你有帮助!如有更多问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

某一个“天” 发表于 2025-1-19 20:22:54

那你别输入a啊,输入w
页: [1]
查看完整版本: 函数中解包参数的困惑