2017-04-12 17 views
1

いくつかのPython構造には、(いつ停止するかを知るために)センチネルが必要なようです。しかし、なぜPyMethodDefの配列のように、複数のNULLで初期化されたセンチネル要素があるのでしょうか?たとえばzipについてはPyMethodDef配列に複数のNULLを含むsentinel要素が必要なのはなぜですか?

static PyMethodDef zip_methods[] = { 
    {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, 
    {NULL,   NULL}   /* sentinel */ 
}; 

なぜ "センチネル配列" の最後のPyMethodDefは2つのNULLのがありますか?なぜただ1つではないのですか?または、__reduce__に4つのエントリがあるとしたら、4 NULLをセンチネル要素として使用しますか?

+0

@OlafなぜCタグを削除するのですか?結局私はここで調べているのはCコードだ。 – MSeifert

+0

"_私は、Cが"停止 "する必要がある時を知るためにはセンチネルが必要であることを認識しています - それは間違っていて、言語の要件もなく、Cのほとんどの配列にも使用されていません。 – Olaf

+0

いいえ、Pythonの実装を間違って前提条件 – Olaf

答えて

3

私はそう思わないでしょう。 2つの理由から:

1)Pythonのソースコードでは、NULLに対して名前をチェックするだけです。

私が知る限り、PyMethodDef配列は2つの場所で使用されます:メソッドを型に結び付けるとき、およびメソッドをモジュールに結びつけるとき。

コードの関連するビットを見つけるには、すべてのタイプがPyType_Readyになり、ほとんどのモジュールがPyModule_Initになるので、そこで検索を開始します。 PyModule_CreatePyModule_Create2に転送されます。 PyType_Readyでは、メソッドは内部関数add_methodsによって処理されます。 PyModule_Create2には、あなた自身が低レベルのものをしたい場合はへのすべての呼び出しがあり、実際にはpublic functionで、内部関数_add_methods_to_objectを呼び出します。

これらの内部関数のどちらも、メソッドをループするforループを持ち、関連する辞書に追加します。 bothcasesでは、ループを継続する条件はmeth->ml_name!=NULLです。

したがって、現在のところ、名前のみがチェックされています。

2)In both C and C++ partial initialization guarantees that the remaining fields are zero/default initialized。したがって、センチネルの最初の要素を0に初期化するだけで、他のすべての要素が0に初期化されます。{}を使用することもできます。

(注意点として、Pythonは巨大であり、あなたはめったに完全で埋める気にしない例PyTypeObjectのために、この自動ゼロ初期化にそれが定義され、大きな構造体との多くを使用しています。)

この回答私を書いた後、これはalready been discussedであることがわかりました。だから、要約で


は - 自動的にゼロが(それは私が彼らが非NULL方法NULL名の使用を見つけた場合、将来的に変更される可能性が推測するように、実装の詳細だが)、およびC Pythonは唯一ml_nameをチェックしますとにかくセンチネル。なぜ私は2つの要素を設定するのが慣習であるのか分かりませんが、条約に従うことから何か言いたいことがあります。

関連する問題