簡體   English   中英

在Python C API中,如果沒有設置第二個參數怎么能默認為第一個的值?

[英]In the Python C API, if the second argument is not set how can I default to the value of the first?

我有一個 x, y 參數。 使用 python C API,如果 y 為 None,我如何將 y 默認為 x 的值。

python 等效項是:

def scale(x: float, y:Optional[float]=None):
    if y is None:
       y = x

    c_scale_api(x, y)

只需對照Py_None檢查它。

static PyObject* scale(PyObject* self, PyObject* args) {
    PyObject* input2 = Py_None; // initialize to None
    double input1d, input2d;
    if (!PyArg_ParseTuple(args, "d|O", &input1d, &input2)) {
        return NULL;
    }
    if (input2 == Py_None)
    {
        input2d = input1d;
    }
    else 
    {
        input2d = PyFloat_AsDouble(input2);
    }
    return PyFloat_FromDouble(input2d);
}

這將返回第二個參數的值供您檢查。

您可以使用| 到 state 解析 arg 元組時,一些 arguments 是可選的。 您必須確保|之后的任何 arguments 在使用它們之前總是有一個值。 也就是說,如果參數不存在, PyArg_ParseTuple將保持變量不變。 通常,這意味着您應該在調用PyArg_ParseTuple之前分配默認值。 但是,由於您的要求,我們可以檢查我們實際獲得了多少個參數,然后如果只給出 1 個參數,則將其分配給y

此代碼將使第二個參數可選,但不完全等同於 python function。 也就是說None不是第二個參數的有效值。 所以scale(1, 2)scale(1)都很好,但是scale(1, None)會失敗。

static PyObject*
scale(PyObject* self, PyObject* args) // type: METH_VARARGS
{
    double x;
    double y;
    if (!PyArg_ParseTuple(args, "d|d", &x, &y)) {
        return NULL;
    }
    if (PyTuple_GET_SIZE(args) == 1) {
        y = x;
    }
    return PyFloat_FromDouble(x + y);
}

對於完全等效的 C function,請嘗試以下操作。 現在像scale(x=1, y=None)這樣的東西也會起作用。

static PyObject* 
scale(PyObject* self, PyObject* args, PyObject* kwargs) // type: METH_VARARGS | METH_KEYWORDS
{
    static char* keywords[] = { "x", "y", NULL };

    double x;
    double y;
    PyObject* y_obj;

    if (
        !PyArg_ParseTupleAndKeywords(
            args, kwargs, "d|O:scale", keywords, &x, &y_obj
        )
     ) {
        return NULL;
    }
    if (y_obj == Py_None) {
        y = x;
    } else if (PyFloat_Check(y_obj)) {
        y = PyFloat_AS_DOUBLE(y_obj);
    } else if (PyLong_Check(y_obj)) {
        y = PyLong_AS_LONG(y_obj);
    } else {
        PyErr_SetString(PyExc_TypeError, "y must be float | int | None");
        return NULL;
    }

    return PyFloat_FromDouble(x + y);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM