python 中的 *args 原理?

python 中的 *args 原理?

args = (1,2,4)

def test_args_kwargs(arg1, arg2, arg3):

print("arg1:", arg1)

print("arg2:", arg2)

print("arg3:", arg3)

test_args_kwargs(*args)

这种写法能够正常运行,但以下这种却不行。

args = (1,2,4)

a,b,c = *args

按理来说,* 具备解包功能,两种赋值的方式应该相同的才对吧?而另一种赋值方式,竟然是可以行。

args = [1,2,4]

a,*b,c = args


回答:

*的语义在不同的场景下会有一些理解上的差别,对于题中出现的几种
1.为什么a,b,c = *args不可以 a,*b,c = args可以?
因为args不一定要平均分割 如果*放在被操作数上 会导致 a,*b = *args 这样的冗余语法 所以这时候放在左边是最简单的

2.a = *args,
args并不是解包赋值给a,而是args解包后和后面元素组成一个tuple再赋值给a

3.为什么test_args_kwargs(*args)可以?
函数的局部变量表就是一个tuple,对于test(a,b,c)需要先把栈中的a b c 组成一个tuple,而test(*args) 则会直接使用args这个tuple,如果args不是tuple 那还是需要先创建tuple


回答:

我想你是把语义理解错了。星号表达式和双星号表达式表示它修饰的容器变量应该 “聚合多个参数” 或 “接收或表示多个单元素”(在同其他变量逗号并列时)。
它表示了修饰容器变量的类型和聚合单元素的方式。
*号本身并不表示拆包动作,拆包动作是在赋值中完成的。

单独使用是错的,语义不明,例如

python">>>> *a = range(5)

>>> a = *range(5)

>>> print(*range(5))

下面是正确的

>>> *a, = range(5)

[0, 1, 2, 3, 4]

>>> a = *range(5),

(0, 1, 2, 3, 4)

>>> *a,b = range(5)

>>> print(*range(5),)

参考:
pep-3132
pep-0448


回答:

*不代表解包,而是展开,或剩余参数。

展开:

  • 函数调用func(a, b, *args, c)

  • 聚合表达式[a, b, *args, c]

剩余参数:

  • 函数定义:def func(a, b, *args)

  • 解构赋值:a, b, *args, c = [...]

无论哪一种,它必须在逗号间隔的 Token 列表中才有意义。

以上是 python 中的 *args 原理? 的全部内容, 来源链接: utcz.com/a/163370.html

回到顶部