Python函数中的最大参数数是多少?

时间:2009-04-03 15:32:14

标签: python function arguments language-features limit

一些常见的知识是Python函数最多可以包含256个参数。我很想知道的是,当*args**kwargs按以下方式展开时,此限制是否适用于此:

items = [1,2,3,4,5,6]

def do_something(*items):
    pass

我问,因为假设可能会出现大于256个项目的列表作为一组*args**kwargs展开的情况。

6 个答案:

答案 0 :(得分:23)

WFM

>>> fstr = 'def f(%s): pass' % (', '.join(['arg%d' % i for i in range(5000)]))
>>> exec(fstr)
>>> f
<function f at 0x829bae4>
Brian注意到

更新:,限制在主叫方:

>>> exec 'f(' + ','.join(str(i) for i in range(5000)) + ')'

Traceback (most recent call last):
  File "<pyshell#63>", line 1, in <module>
    exec 'f(' + ','.join(str(i) for i in range(5000)) + ')'
  File "<string>", line 1
SyntaxError: more than 255 arguments (<string>, line 1)

另一方面,这有效:

>>> f(*range(5000))
>>> 

结论:不,它不适用于展开的参数。

答案 1 :(得分:22)

限制是由于编译的字节码如何处理使用位置参数和/或关键字参数调用函数。

关注的字节码op是CALL_FUNCTION,它携带长度为4个字节的op_arg,但是使用了两个最低有效字节。其中,最重要的字节表示堆栈上关键字参数的数量,最低有效字节表示堆栈上位置参数的数量。因此,您最多可以拥有0xFF == 255个关键字参数或0xFF == 255个位置参数。

此限制不适用于*args**kwargs,因为使用该语法的调用使用字节码操作CALL_FUNCTION_VARCALL_FUNCTION_KWCALL_FUNCTION_VAR_KW,具体取决于签名。对于这些操作码,堆栈由*args的可迭代和dict的{​​{1}}组成。这些物品直接传递给接收器,接收器根据需要展开它们。

答案 2 :(得分:10)

在Python 3.7之前的版本中,CPython在调用中具有255个显式传递参数的限制:

>>> def f(*args, **kwargs): pass
...
>>> exec("f({})".format(', '.join(map(str, range(256)))))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
SyntaxError: more than 255 arguments

这个限制已经存在,因为在Python 3.5之前,CALL_FUNCTION opcode重载了操作码参数,以编码堆栈上的位置和关键字参数的数量,每个参数都编码在一个字节中。

在即将发布的Python 3.7版本中删除了此限制,请参阅issue #27213issue #12844; #27213重新设计了CALL_FUNCTION*操作码系列的性能和简单性(3.6的一部分),释放了操作码参数以仅编码单个参数计数,#12844删除了编译时检查,阻止了具有更多参数的代码从编译。

在3.7中,使用EXTENDED_ARG() opcode,现在没有任何限制可以使用显式参数传递多少个参数,保存可以装入堆栈的数量(现在被你的记忆束缚住了):

>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=7, micro=0, releaselevel='alpha', serial=2)
>>> def f(*args, **kwargs): pass
...
>>> exec("f({})".format(', '.join(map(str, range(256)))))
>>> exec("f({})".format(', '.join(map(str, range(2 ** 16)))))

请注意,列表,元组和词典仅限于sys.maxsize个元素,因此如果被调用函数使用*args和/或**kwargs catch-all参数,那么有限。

对于*args**kwargs调用语法(扩展参数),除了Python标准类型的相同sys.maxint大小限制之外,没有其他限制。

答案 3 :(得分:5)

这似乎是编译源代码的限制,因此可能只存在于直接传递的参数,而不是* args或** kwargs。

相关代码可在ast.c中找到:

if (nargs + nkeywords + ngens > 255) {
  ast_error(n, "more than 255 arguments");
  return NULL;
}

但请注意,这是在ast_for_call中,因此仅适用于主叫方。即f(a,b,c,d,e...),而不是定义,但它会计算位置(a,b,c,d)keyword (a=1, b=2, c=3)样式参数。实际的*args**kwargs参数在调用方看起来只应作为一个参数用于这些目的。

答案 4 :(得分:1)

对于** kwargs,如果我记得很清楚,这是一本字典。因此它没有任何限制。

对于* args,我不太确定,但我认为它是一个元组或列表,所以它也没有限制。

无限制,我的意思是除了内存限制。

答案 5 :(得分:0)

我尝试了4000个项目的列表,并且它有效。所以我猜它也适用于更大的值。