为什么 *args 参数解包会给出一个元组?

在 python 中,可以定义一个带有任意数量的位置参数的函数,如下所示:


def f(*args):

    print(args)

f(1, 2, 3)  # (1, 2, 3)

当调用 as 时f(a, b, c),所有位置参数都放在一个元组中。这种行为在 python 2和3文档中有所描述,但我还没有找到它的 PEP。


PEP 3132,first, *middle, last = seqence在“接受”下引入扩展的可迭代解包 ( ) 状态,即


使加星标的目标成为元组而不是列表。这将与函数的 *args 一致,但会使结果的进一步处理更加困难。


进行了讨论。如果我写了一个包装器,我可能还想进一步处理这样的参数:


def force_type(position, type):

    def wrapper(f):

        def new(*args, **kwargs):

            args = list(args)  # Why?

            args[position] = type(args[position])

            return f(*args, **kwargs)

        return new

    return wrapper


@force_type(1, int)

def func(a, b, c):

    assert isinstance(b, int)

这进一步处理由较硬的事实args是一个tuple。在引入的早期阶段是否没有使用包装器?如果是这样,为什么这在 python3 中没有通过其他兼容性破坏性更改进行更改(PEP3132 更倾向于易于处理而不是一致性(这似乎至少类似于兼容性破坏性更改中的兼容性)。


为什么 a 函数*args(仍然)atuple即使 alist允许更容易的进一步处理?


缥缈止盈
浏览 255回答 3
3回答

慕斯王

我不知道这是否是它背后的想法,但是处理的简便性(即list使用tuple数据实例化 a并不难)可能会出现令人困惑的行为。def fce1(*args):   fce2(args)   # some more code using argsdef fce2(args):   args.insert(0, 'other_val')fce1(1, 2, 3)编写fce1代码的人可能会感到惊讶,因为args他们没有意识到他们稍后处理的不是调用函数的内容。我还认为不可变类型在内部更容易处理并且开销更少。

MMTTMM

我最好的猜测是,如果 *args 生成一个列表(可变),它会在多种情况下导致非常令人惊讶的结果。@Ondrej K. 给出了一个很好的例子。打个比方,当有一个列表作为默认参数时,每个函数调用可能有不同的默认参数。这是默认参数只计算一次的结果,这种情况不是最直观的。即使是官方的 python 文档也有针对这种情况的特定解决方法。执行函数定义时从左到右计算默认参数值。这意味着表达式会在定义函数时计算一次,并且每次调用都使用相同的“预计算”值。这对于理解何时默认参数是可变对象(例如列表或字典)尤其重要:如果函数修改了对象(例如,通过将项目附加到列表),则默认值实际上被修改了。这通常不是预期的。解决这个问题的一种方法是使用 None 作为默认值,并在函数体中明确测试它,例如:def whats_on_the_telly(penguin=None):if penguin is None:    penguin = []penguin.append("property of the zoo")return penguin总而言之,我认为 *args 是一个元组,因为将它作为列表会导致与可变类型相关的所有问题(如速度较慢),更大的问题是大多数人不希望函数参数发生变化。尽管我确实同意这种实现与PEP-3132非常不一致,并且会导致大多数学习者感到困惑。我对 Python 非常陌生,为了与PEP-3132 的接受保持一致,我花了一段时间才理解 *args 成为元组而不是列表的原因可能是什么。

幕布斯7119047

为什么不?关于元组的事情是,你不能在创建后改变它。这允许提高执行脚本的速度,并且您实际上不需要函数参数列表,因为您实际上不需要修改函数的给定参数。你需要为你的参数附加或删除方法吗?在大多数情况下,它不会。你想让你的程序运行得更快吗?那会是的。这就是大多数人喜欢拥有东西的方式。*args 的东西因此返回元组,如果你真的需要一个列表,你可以用一行代码来转换它!args = list(args)所以总的来说:它可以加快您的程序执行速度。你不要改变论据。改变它的类型并不难。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python