19

私は Python 用の C 拡張機能を作成する方法を学ぼうとしており、PyArg_ParseTupleAndKeywords がどのように機能するかを確実に理解したいと考えています。

最初の引数は、渡された順序で C 拡張関数に渡される引数の配列を指す PyObject ポインターであると思います。2 番目の引数は、渡されたキーワードのリスト、それらが渡された位置、およびキーワードがどの位置で始まり、その位置が無関係になるかを示す何らかの標識フラグである可能性が非常に高いです。

次に、PyArg_ParseTupleAndKeywords は、キーワードのリスト (4 番目の引数) を使用して、キーワードで指定された引数と、適切な値がコピーされるフォーマット文字列 (3 番目の引数) と C 変数のアドレス (5 番目 & + 引数) の両方をマップします。

私の理解は正しいですか?オンライン ドキュメントを読んでいると、「位置引数とキーワード引数」への参照しか表示されず、少し暗い気分になります。PyArg_ParseTupleAndKeywords を処理する Python インタープリターのファイルはどこにありますか?

4

2 に答える 2

16

Python で以下をエミュレートするには:

def keywords(a, b, foo=None, bar=None, baz=None):
    pass

以下が機能します。

static PyObject *keywords(PyObject *self, PyObject *args, PyObject *kwargs)
{
    char *a;
    char *b;
    char *foo = NULL;
    char *bar = NULL;
    char *baz = NULL;

    // Note how "a" and "b" are included in this
    // even though they aren't supposed to be in kwargs like in python
    static char *kwlist[] = {"a", "b", "foo", "bar", "baz", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|sss", kwlist, 
                                     &a, &b, &foo, &bar, &baz)) 
    {
        return NULL;
    }

    printf("a is %s\n", a);
    printf("b is %s\n", b);
    printf("foo is %s\n", foo);
    printf("bar is %s\n", bar);
    printf("baz is %s\n", baz);

    Py_RETURN_NONE;
}

// ...

static PyMethodDef SpamMethods[] = 
{
    // ...
    {"keywords", (PyCFunction) keywords, METH_VARARGS | METH_KEYWORDS, "practice kwargs"},
    {NULL, NULL, 0, NULL}
    // ...
}

そしてそれを使用するには:

from spam import keywords

keywords()         # Fails, require a and b
keywords('a')      # fails, requires b
keywords('a', 'b')
keywords('a', 'b', foo='foo', bar='bar', baz='baz') 
keywords('a', 'b','foo', 'bar', 'baz')
keywords(a='a', b='b', foo='foo', bar='bar', baz='baz')
于 2017-02-12T21:19:07.787 に答える
8

http://docs.python.org/c-api/arg.htmlの冒頭の説明を読みましたか? 何が起こっているのかを説明するのにかなり良い仕事をしています。の特定の参照に直接行かないでくださいPyArg_ParseTupleAndKeywords。上記のテキストを読んでいることを前提としており、それ自体はあまり役に立ちません。

しかし、あなたはほとんどそれを手に入れました。最初の引数は、確かに受信位置引数のリストです。2 つ目は、入力キーワード引数のマップです (指定されたキーワード名を指定された値にマッピングします)。4 番目の引数は、実際には、関数が受け入れる準備ができているキーワードのリストです。はい、3 番目の引数はフォーマット文字列で、5 番目以降は値がコピーされる C ポインターです。

PyArg_ParseTupleAndKeywords()の下にありますPython/getargs.c

于 2012-05-16T20:12:01.403 に答える