25

これは、Pythonドキュメント(http://docs.python.org/extending/extending.html)の簡単な例です。

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

追加のブールパラメータを関数に渡したい場合-それを行うための「正しい」方法は何ですか?

PyArg_ParseTuple()に渡すboolオプションはないようです。だから私は次のことを考えました:

  1. 整数を読み取り、値を使用するだけです(boolはintのサブクラスであるため)
  2. 整数でPyBool_FromLong()を呼び出す
  3. 読み取り、オブジェクトを作成し、PyBool_Check()を呼び出して、ブール値であることを確認します
  4. おそらく、任意のタイプの変数を取得してその真理値を取得する方法があります(つまり、空の配列は偽物などです)。これは、Python関数が通常行うことです。

これらのいずれかが望ましいですか?別のオプション?

4

3 に答える 3

23

4 おそらく、任意のタイプの変数を取得し、その真の値を取得する方法 (つまり、空の配列は Falsy など) がある可能性があります。これは、Python 関数が通常行うことです。

はい: ( Python/C API リファレンスから)

int PyObject_IsTrue(PyObject *o)

オブジェクト o が true であると見なされる場合は 1 を返し、そうでない場合は 0 を返します。これは、Python の式 not not o と同等です。失敗すると -1 を返します。

編集。実際の質問に答えるには、C では int が実際に対応する型であるため、アプローチ 1 が正しいと思います。アプローチ 4 は適切ですが、関数が bool を取ると文書化する場合、任意のオブジェクトを受け入れる義務はありません。3 のような理由のない明示的な型チェックは、Python では嫌われます。2 のような別の Python オブジェクトへの変換は、C コードの役に立ちません。

于 2012-02-16T17:52:53.433 に答える
17

"i"現在、ブール値を取得する方法として、整数の解析 ( as ) が受け入れられています。

Python 3.3 からは、最新の NEWSに従って (「述語」の場合)PyArg_ParseTuple受け入れます:"p"

  • 問題 #14705 : PyArg_Parse() ファミリの関数は、「ブール述語」引数を受け入れる「p」フォーマット ユニットをサポートするようになりました。任意の Python 値を整数に変換します。「false」の場合は 0、それ以外の場合は 1 です。

PyArg_ParseTuplewith を使用する"p"場合、引数intは C99bool型ではなく (pointer to) でなければならないことに注意してください。

int x;    // not "bool x"
PyArg_ParseTuple(args, kwds, "p", &x);
于 2012-05-22T11:01:48.947 に答える
7

私は別のアプローチを見つけました:

PyObject* py_expectArgs;
bool expectArgs;

PyArg_ParseTupleAndKeywords(args, keywds, (char *)"O!", (char **)kwlist, &PyBool_Type, &py_expectArgs);

expectArgs = PyObject_IsTrue(py_expectArgs);

間違ったパラメーター呼び出しの場合、「自動」例外「引数 1 は int ではなく bool でなければなりません」

于 2013-09-16T11:45:41.617 に答える