首页 > 解决方案 > 如何对 PyObject* 字符串使用基本字符串操作?

问题描述

我不想继续将每个 Python 字符串对象从PyUnicode_DecodeUTF8 和 PyUnicode_AsUTF8 转换PyObject*std::stringchar*使用PyUnicode_DecodeUTF8PyUnicode_AsUTF8,因为这是一项昂贵的操作。

关于我的最后一个问题如何扩展/重用 Python C 扩展/API 实现?,我设法使用Pythonopen函数,直接给我一个PyObject*字符串。一旦这样做,将字符串发送回 Python 程序就非常简单,因为我可以将其指针传回,而不是像or那样PyObject*进行完整的逐字符复制。PyUnicode_DecodeUTF8PyUnicode_AsUTF8

regexCPython API 的实现上,我可以找到这样的函数

static void* getstring(PyObject* string, Py_ssize_t* p_length,
          int* p_isbytes, int* p_charsize,
          Py_buffer *view)
{
    /* given a python object, return a data pointer, a length (in
       characters), and a character size.  return NULL if the object
       is not a string (or not compatible) */

    /* Unicode objects do not support the buffer API. So, get the data directly. */
    if (PyUnicode_Check(string)) {
        if (PyUnicode_READY(string) == -1)
            return NULL;
        *p_length = PyUnicode_GET_LENGTH(string);
        *p_charsize = PyUnicode_KIND(string);
        *p_isbytes = 0;
        return PyUnicode_DATA(string);
    }

    /* get pointer to byte string buffer */
    if (PyObject_GetBuffer(string, view, PyBUF_SIMPLE) != 0) {
        PyErr_SetString(PyExc_TypeError, "expected string or bytes-like object");
        return NULL;
    }
    *p_length = view->len;
    *p_charsize = 1;
    *p_isbytes = 1;

    if (view->buf == NULL) {
        PyErr_SetString(PyExc_ValueError, "Buffer is NULL");
        PyBuffer_Release(view);
        view->buf = NULL;
        return NULL;
    }
    return view->buf;
}

它似乎没有使用PyUnicode_DecodeUTF8PyUnicode_AsUTF8使用PyObject*来自 Python Interpreter 的内容。

如何在PyObject*不转换为std::stringor的情况下对字符串使用基本字符串操作char*

我将基本操作称为以下示例:(只是为了举例,我使用 Py_BuildValue 将PyObject*字符串从字符串构建为 a char*or std::string

static PyObject* PyFastFile_do_concatenation(PyFastFile* self)
{
    PyObject* hello = Py_BuildValue( "s", "Hello" );
    PyObject* word = Py_BuildValue( "s", "word" );

    // I am just guessing the `->value` property
    PyObject* hello_world = hello->value + word->value;
    hello_world; // return the `PyObject*` string `Hello word`
}

static PyObject* PyFastFile_do_substring(PyFastFile* self)
{
    PyObject* hello = Py_BuildValue( "s", "Hello word" );
    PyObject* hello_world = hello->value[5:];
    hello_world; // return the `PyObject*` string `word`
}

static PyObject* PyFastFile_do_contains(PyFastFile* self)
{
    PyObject* hello = Py_BuildValue( "s", "Hello word" );

    if( "word" in hello->value ) {
        Py_BuildValue( "p", true ); // return the `PyObject*` boolean `true`
    }
    Py_BuildValue( "p", false ); // return the `PyObject*` boolean `false`
}

标签: pythonpython-c-api

解决方案


推荐阅读