Каково максимальное количество аргументов в функции Python?

Общеизвестно, что функции Python могут содержать не более 256 аргументов. Мне интересно узнать, подходит ли это ограничение для *args и **kwargs, когда они разворачиваются следующим образом:

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

def do_something(*items):
    pass

Я спрашиваю, потому что, предположительно, могут быть случаи, когда список размером более 256 элементов разворачивается как набор *args или **kwargs.

Ответ 1

WFM

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

Обновление:, как заметил Брайан, предел находится на стороне вызова:

>>> 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))
>>> 

Вывод: нет, он не применяется к развернутым аргументам.

Ответ 2

Предел связан с тем, как скомпилированный байт-код рассматривает вызов функции с аргументами позиции и/или аргументами ключевого слова.

Байт-код op проблемы - CALL_FUNCTION который содержит op_arg длиной 4 байта, но используется два младших значащих байта. Из них наиболее значимый байт представляет количество аргументов ключевого слова в стеке и наименее значимый байт - количество позиционных аргументов в стеке. Следовательно, вы можете иметь не более 0xFF == 255 аргументов ключевого слова или 0xFF == 255 позиционных аргументов.

Это ограничение не распространяется на *args и **kwargs потому что вызовы с этой грамматикой используют bytecode ops CALL_FUNCTION_VAR, CALL_FUNCTION_KW и CALL_FUNCTION_VAR_KW зависимости от подписи. Для этих кодов операций стек состоит из итерации для *args и dict для **kwargs. Эти элементы передаются непосредственно получателю, который разворачивает их по мере необходимости.

Ответ 3

В версиях до 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 перегружал аргумент кода операции, чтобы кодировать как количество аргументов positional, так и ключевого слова в стеке, каждый из которых закодирован в одном байте.

Это ограничение удаляется в предстоящей версии Python 3.7, см. Вопрос № 27213 и номер # 12844; # 27213 переработал семейство CALL_FUNCTION* для производительности и простоты (часть 3.6), освободив аргумент аргумента opcode только для кодирования одного аргумента, а # 12844 удалил проверку времени компиляции, которая предотвратила компиляцию кода с большим количеством аргументов,

В 3.7 с EXTENDED_ARG() операции EXTENDED_ARG() теперь нет ограничений на то, сколько аргументов вы можете передать с использованием явных аргументов, за исключением того, сколько из них может быть установлено в стек (так привязано теперь вашей памятью):

>>> 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 (расширяющих аргументы) нет ограничений, кроме тех же sys.maxint размера sys.maxint для стандартных типов Python.

Ответ 4

Это, по-видимому, является ограничением при компиляции источника, поэтому, вероятно, существует только для передаваемых аргументов напрямую, а не в * 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 выглядят так, как будто они должны считать только один аргумент для этих целей на вызывающей стороне.

Ответ 5

для ** kwargs. Если я хорошо помню, это словарь. Поэтому он не имеет никаких ограничений.

для * args, я не уверен, но я думаю, что это кортеж или список, поэтому он также не имеет никаких ограничений.

Без ограничений я имею в виду, кроме, возможно, ограничения памяти.

Ответ 6

Я попробовал список из 4000 элементов, и он сработал. Поэтому я предполагаю, что он будет работать и для больших значений.