2012-02-16 18 views
19

これは、Pythonドキュメント(http://docs.python.org/extending/extending.html)から簡単な例である:私は関数に追加のブール・パラメータを渡したい場合はブール値をPython C拡張に渡す「正しい」方法は何ですか?

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()に渡すブールオプションがないようです。 (整数

  • 読み取りおよびオブジェクト上)
  • コールPyBool_FromLong(

    1. は、整数を読み、(ブール値がintのサブクラスであるとして)値だけを使用し、PyBool_Checkを呼び出します。だから私は、次の考え)それがboolであることを確認するには
    2. 多分、変数の型を取得し、その真理値を得る方法があります(空の配列は偽であるなど)。これはPython関数が通常行うことです。

    これらのいずれかが好ましいですか?その他のオプション?

  • 答えて

    16

    4は、多分、変数のいずれかのタイプを取得し、その真理値を取得する方法がありますのpython 機能は通常、何をすべきかである(すなわち、空の配列意志falsyなどです)。

    はい:

    int PyObject_IsTrue(PyObject *o) 
    

    返し、さもなければオブジェクトOが真であると考えられる場合は1、及び0(Python/C API Referenceから)。 これはoでないPython式と同じです。失敗した場合、 は-1を返します。

    EDIT。実際の質問に答えるためには、アプローチ1は正しいと思います。なぜなら、intは実際にはCの対応する型だからです。アプローチ4は良いですが、boolを取って関数を記述すると、オブジェクトを受け入れる義務はありません。理由のない3のような明示的な型チェックは、Pythonで戸惑う。 2のように別のPythonオブジェクトに変換しても、Cコードは役に立ちません。

    13

    現在、整数を解析すると("i")、受け入れられる方法がboolになります。

    パイソン3.3

    PyArg_ParseTuplethe latest NEWSあたり、( "述語" のため)"p"受け入れる:

    • Issue #14705を:関数のPyArg_Parse()ファミリーは現在、 'P' フォーマット ユニットを支持します「ブール述語」引数を受け取ります。 Python の値を整数に変換します。「false」の場合は0、そうでない場合は1に変換します。

    "p"PyArg_ParseTupleを使用する場合、引数は(ポインタ)はint、ないC99 boolタイプでなければならないことに注意してください。

    int x; // not "bool x" 
    PyArg_ParseTuple(args, kwds, "p", &x); 
    
    +2

    私はこれを使って、Cで変数を 'int'(' bool'ではなく)として宣言する必要があることを発見しました。あるいは、複数のboolを使用する場合、正しく設定されません(おそらく、 'bool'と' int'の間のサイズの違いに関する問題)。 – szmoore

    +0

    @szmooreここでは、応答に整数を使用すると記載されています。 – kevr

    +0

    はい、そうですが、Cでは 'int'と' bool'を同じ意味で使うことができます。この場合はできません。私はそれが超流動性の場合、私のコメントを削除することができます。 – szmoore

    6

    私は別のアプローチを発見した:

    PyObject* py_expectArgs; 
    bool expectArgs; 
    
    PyArg_ParseTupleAndKeywords(args, keywds, (char *)"O!", (char **)kwlist, &PyBool_Type, &py_expectArgs); 
    
    expectArgs = PyObject_IsTrue(py_expectArgs); 
    

    間違ったparam呼び出しの場合、 "auto"例外 "引数1はintでなくboolでなければなりません"

    関連する問題