39

Python 関数が最大 256 個の引数を持つことができることは、ある程度一般的な知識です。私が知りたいのは、この制限が適用されるかどうか、*argsおよび**kwargs次の方法でアンロールされる場合です。

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

def do_something(*items):
    pass

仮説として、256 項目を超えるリストが*argsまたはのセットとして展開される場合があるかもしれないので、質問し**kwargsます。

4

6 に答える 6

22

Python 3.6以前では、制限は、コンパイルされたバイトコードが位置引数やキーワード引数を使用した関数の呼び出しをどのように処理するかによるものです。

問題のバイトコードopは、長さが4バイトのバイトコードCALL_FUNCTIONを伝送しop_argますが、最下位2バイトが使用されます。これらのうち、最上位バイトはスタック上のキーワード引数の数を表し、最下位バイトはスタック上の位置引数の数を表します。0xFF == 255したがって、最大でキーワード引数または0xFF == 255位置引数を持つことができます。

*argsこの制限は適用されません。その文法を使用する呼び出しは、署名に応じて**kwargsバイトコードops 、、CALL_FUNCTION_VARを使用するためです。これらのオペコードの場合、スタックは、の反復可能オブジェクトとの反復可能オブジェクトで構成されます。これらのアイテムは、必要に応じて展開するレシーバーに直接渡されます。CALL_FUNCTION_KWCALL_FUNCTION_VAR_KW*argsdict**kwargs

于 2012-01-19T19:36:03.867 に答える
22

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

結論:いいえ、展開された引数には適用されません。

于 2009-04-03T15:44:51.537 に答える
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パラメーターは、呼び出し側でこれらの目的のために 1 つの引数としてのみカウントする必要があるように見えます。

于 2009-04-03T16:45:42.063 に答える
0

**kwargs の場合、よく覚えていれば、これは辞書です。したがって、制限はほとんどありません。

*argsについては、よくわかりませんが、タプルかリストだと思いますので、制限もほぼありません。

制限なしとは、おそらくメモリ制限を除いて意味します。

于 2009-04-03T15:46:26.870 に答える
-1

4000 項目のリストを試してみましたが、うまくいきました。したがって、より大きな値でも機能すると思います。

于 2009-04-03T15:35:43.633 に答える