python - 如何对 PyObject* 字符串使用基本字符串操作?
问题描述
我不想继续将每个 Python 字符串对象从PyUnicode_DecodeUTF8 和 PyUnicode_AsUTF8 转换PyObject*
为std::string
或char*
使用PyUnicode_DecodeUTF8和PyUnicode_AsUTF8,因为这是一项昂贵的操作。
关于我的最后一个问题如何扩展/重用 Python C 扩展/API 实现?,我设法使用Pythonopen
函数,直接给我一个PyObject*
字符串。一旦这样做,将字符串发送回 Python 程序就非常简单,因为我可以将其指针传回,而不是像or那样PyObject*
进行完整的逐字符复制。PyUnicode_DecodeUTF8
PyUnicode_AsUTF8
在regex
CPython 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_DecodeUTF8
或PyUnicode_AsUTF8
使用PyObject*
来自 Python Interpreter 的内容。
如何在PyObject*
不转换为std::string
or的情况下对字符串使用基本字符串操作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`
}
解决方案
推荐阅读
- jenkins - 为什么我不能远程连接 Jenkins?
- java - java如何强制刷新url连接
- javascript - Webpack + Express,根据视图提供特定的 js 文件
- flutter - dart/flutter:创建后指定 HSLColor 的饱和度
- android - id_token 缺少使用 OpenID Connect 的 AD FS 2016 的自定义声明
- php - Laravel 项目中的 Voyager 无法在实时服务器上找到 CSS
- spring-boot - 用于 Spring Boot 的自定义 KeyManager 和 TrustManager
- pandas - 大熊猫中的分组总和和平均值并制作数据框
- java - 如何从另一个线程的函数中抛出异常?
- javascript - 正确传递结构(js)