首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python函数中参数的最大数量是多少?

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

Stack Overflow用户
提问于 2009-04-03 15:32:14
回答 6查看 35.5K关注 0票数 39

Python函数最多可以有256个参数,这在一定程度上是常识。我想知道的是,当*args**kwargs以以下方式展开时,这一限制是否适用于它们:

代码语言:javascript
运行
复制
items = [1,2,3,4,5,6]

def do_something(*items):
    pass

我之所以这样问,是因为假设可能存在这样的情况:一个超过256个条目的列表会以一组*args**kwargs的形式展开。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2018-01-02 00:46:21

在Python 3.7和更新版本中,没有限制。这是在issue #27213issue #12844中完成的工作的结果;#27213为了性能和简单性重新编写了CALL_FUNCTION*操作码系列(3.6中的一部分),释放了操作码参数以仅编码单个参数计数,并且#12844删除了阻止具有更多参数的代码被编译的编译时检查。

因此,从3.7开始,对于EXTENDED_ARG() opcode,您可以使用显式参数传递的参数数量没有任何限制,除了可以放在堆栈中的参数数量(所以现在由您的内存约束):

代码语言:javascript
运行
复制
>>> 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捕获所有参数,则这些参数是有限的。

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

在Python3.7之前的版本中,CPython在一个调用中有255个显式传递的参数的限制:

代码语言:javascript
运行
复制
>>> 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

之所以存在这种限制,是因为在Python3.5之前,CALL_FUNCTION opcode重载了操作码参数来编码堆栈上的位置参数和关键字参数的数量,每个参数都编码在一个字节中。

票数 20
EN

Stack Overflow用户

发布于 2009-04-03 15:44:52

WFM

代码语言:javascript
运行
复制
>>> fstr = 'def f(%s): pass' % (', '.join(['arg%d' % i for i in range(5000)]))
>>> exec(fstr)
>>> f
<function f at 0x829bae4>

更新:正如布莱恩所注意到的,限制是在调用端:

代码语言:javascript
运行
复制
>>> 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)

另一方面,这是可行的:

代码语言:javascript
运行
复制
>>> f(*range(5000))
>>> 

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

票数 22
EN

Stack Overflow用户

发布于 2012-01-20 03:36:04

在Python 3.6和更早版本中,该限制是由于编译的字节码如何处理使用位置参数和/或关键字参数调用函数。

值得关注的字节码op是CALL_FUNCTION,它携带长度为4字节的op_arg,但在两个最低有效字节上使用。其中,最高有效字节表示堆栈上关键字参数的数量,最低有效字节表示堆栈上位置参数的数量。因此,最多只能有0xFF == 255关键字参数或0xFF == 255位置参数。

此限制不适用于*args**kwargs,因为使用该语法的调用将根据签名使用字节码操作CALL_FUNCTION_VARCALL_FUNCTION_KWCALL_FUNCTION_VAR_KW。对于这些操作码,堆栈由用于*args的迭代器和用于**kwargs的迭代器组成。这些项目被直接传递到接收器,接收器根据需要展开它们。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/714475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档