¿Qué es un número máximo de argumentos en una función de Python?

Es algo común saber que las funciones de Python pueden tener un máximo de 256 argumentos. Lo que tengo curiosidad por saber es si este límite se aplica a *args y **kwargs cuando se desenrollan de la siguiente manera:

 items = [1,2,3,4,5,6] def do_something(*items): pass 

Lo pregunto porque, hipotéticamente, podría haber casos en los que una lista de más de 256 elementos se desenrolle como un conjunto de *args o **kwargs .

WFM

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

Actualización: como Brian notó, el límite está en el lado de la llamada:

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

Por otro lado esto funciona:

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

Conclusión: no, no se aplica a los argumentos desenrollados.

El límite se debe a cómo el código de bytes comstackdo trata de llamar a una función con argumentos de posición y / o argumentos de palabras clave.

La CALL_FUNCTION bytecode de interés es CALL_FUNCTION que lleva un op_arg que tiene 4 bytes de longitud, pero en los dos bytes menos significativos se utilizan. De ellos, el byte más significativo representa el número de argumentos de palabras clave en la stack y el byte menos significativo el número de argumentos posicionales en la stack. Por lo tanto, puede tener como máximo 0xFF == 255 argumentos de palabra clave o 0xFF == 255 argumentos posicionales.

Este límite no se aplica a *args y **kwargs porque las llamadas con esa gramática utilizan las operaciones de bytecode CALL_FUNCTION_VAR , CALL_FUNCTION_KW y CALL_FUNCTION_VAR_KW dependiendo de la firma. Para estos opcodes, la stack consiste en un iterable para *args y un dict para los **kwargs . Estos elementos se pasan directamente al receptor, que se desenrolla según sea necesario.

En versiones anteriores a Python 3.7, CPython tiene un límite de 255 argumentos pasados ​​explícitamente en una llamada:

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

Esta limitación está en su lugar porque hasta Python 3.5, el CALL_FUNCTION operación CALL_FUNCTION sobrecargó el argumento del código de operación para codificar el número de argumentos posicionales y de palabras clave en la stack, cada uno codificado en un solo byte.

Esta limitación se elimina en la próxima versión de Python 3.7, vea el problema # 27213 y el problema # 12844 ; # 27213 CALL_FUNCTION* familia de opcodes CALL_FUNCTION* por desempeño y simplicidad (parte de 3.6), liberando el argumento de opcode para codificar solo un conteo de argumentos único, y # 12844 eliminó la verificación en tiempo de comstackción que impidió que se comstackra el código con más argumentos .

En la EXTENDED_ARG() 3.7, con el código de operación EXTENDED_ARG() , ahora no hay ningún límite en la cantidad de argumentos que puede pasar utilizando argumentos explícitos, guarde la cantidad que se puede incluir en la stack (así que ahora está vinculada por su memoria):

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

Tenga en cuenta que las listas, las tuplas y los diccionarios están limitados a los elementos sys.maxsize , por lo que si la función llamada utiliza los parámetros catch-all *args y / o **kwargs , entonces esos son limitados.

Para la syntax de llamadas *args y **kwargs (expandiendo argumentos) no hay límites distintos de los mismos límites de tamaño sys.maxint en los tipos estándar de Python.

Esto parece ser una restricción en la comstackción de la fuente, por lo que probablemente existirá solo para los argumentos que se pasen directamente, no en * args o ** kwargs.

El código relevante se puede encontrar en ast.c :

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

Pero tenga en cuenta que esto está en ast_for_call, y por lo tanto solo se aplica al lado llamante. es decir, f(a,b,c,d,e...) , en lugar de la definición, aunque contará tanto posicional (a,b,c,d) como keyword (a=1, b=2, c=3) parámetros de estilo. Los parámetros reales *args y **kwargs parecen que solo deberían contar como un argumento para estos fines en el lado de la llamada.

para ** kwargs, si recuerdo bien, esto es un diccionario. Por lo tanto, no tiene límites.

para * args, no estoy tan seguro, pero creo que es una tupla o una lista, por lo que tampoco tiene límites.

Sin límites, quiero decir, excepto tal vez el límite de la memoria.

Intenté una lista de 4000 artículos, y funcionó. Así que supongo que también funcionará para valores más grandes.