python3 str对象不能通过PyUnicode_Check
python3 str object cannot pass PyUnicode_Check
我正在编写一个 C 扩展函数,它应该接受一个 str
对象作为参数。代码如下所示:
static PyObject *py_print_chars(PyObject *self, PyObject *o) {
PyObject *bytes;
char *s;
if (!PyUnicode_Check(o)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(o);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
Py_RETURN_NONE;
}
但是当我在 python3 控制台中测试模块时,我发现 str
对象无法通过 PyUnicode_Check
:
>>> from sample2 import *
>>> print_chars('Hello world')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Expected string
据我所知,Python3的str()
类型在C语言中称为PyUnicode,上面的C代码是参考"python cookbook3"Char15.13编写的。我只是无法解决这个问题。谁能告诉我我的代码有什么问题。
这是 "python cookbook3" 所说的:
如果由于某种原因,您直接使用 PyObject * 而不能使用 PyArg_ParseTuple(),以下代码示例显示了如何检查和提取合适的 char *
引用,来自字节和字符串对象:
/* Some Python Object (obtained somehow) */
PyObject *obj;
/* Conversion from bytes */
{
char *s;
s = PyBytes_AsString(o);
if (!s) {
return NULL; /* TypeError already raised */
}
print_chars(s);
}
/* Conversion to UTF-8 bytes from a string */
{
PyObject *bytes;
char *s;
if (!PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(obj);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
}
以及整个代码:
#include "Python.h"
#include "sample.h"
static PyObject *py_print_chars(PyObject *self, PyObject *o) {
PyObject *bytes;
char *s;
if (!PyUnicode_Check(o)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(o);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
Py_RETURN_NONE;
}
/* Module method table */
static PyMethodDef SampleMethods[] = {
{"print_chars", py_print_chars, METH_VARARGS, "print character"},
{ NULL, NULL, 0, NULL}
};
/* Module structure */
static struct PyModuleDef samplemodule = {
PyModuleDef_HEAD_INIT,
"sample",
"A sample module",
-1,
SampleMethods
};
/* Module initialization function */
PyMODINIT_FUNC
PyInit_sample2(void) {
return PyModule_Create(&samplemodule);
}
如果目标是只接受一个参数,则函数 should be declared as METH_O
,而不是 METH_VARARGS
;前者在不包装的情况下传递单个参数,后者包装在 tuple
中,需要对其进行解压缩或解析才能在其中获取 PyUnicode*
。
我正在编写一个 C 扩展函数,它应该接受一个 str
对象作为参数。代码如下所示:
static PyObject *py_print_chars(PyObject *self, PyObject *o) {
PyObject *bytes;
char *s;
if (!PyUnicode_Check(o)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(o);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
Py_RETURN_NONE;
}
但是当我在 python3 控制台中测试模块时,我发现 str
对象无法通过 PyUnicode_Check
:
>>> from sample2 import *
>>> print_chars('Hello world')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Expected string
据我所知,Python3的str()
类型在C语言中称为PyUnicode,上面的C代码是参考"python cookbook3"Char15.13编写的。我只是无法解决这个问题。谁能告诉我我的代码有什么问题。
这是 "python cookbook3" 所说的:
如果由于某种原因,您直接使用 PyObject * 而不能使用 PyArg_ParseTuple(),以下代码示例显示了如何检查和提取合适的 char *
引用,来自字节和字符串对象:
/* Some Python Object (obtained somehow) */
PyObject *obj;
/* Conversion from bytes */
{
char *s;
s = PyBytes_AsString(o);
if (!s) {
return NULL; /* TypeError already raised */
}
print_chars(s);
}
/* Conversion to UTF-8 bytes from a string */
{
PyObject *bytes;
char *s;
if (!PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(obj);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
}
以及整个代码:
#include "Python.h"
#include "sample.h"
static PyObject *py_print_chars(PyObject *self, PyObject *o) {
PyObject *bytes;
char *s;
if (!PyUnicode_Check(o)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(o);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
Py_RETURN_NONE;
}
/* Module method table */
static PyMethodDef SampleMethods[] = {
{"print_chars", py_print_chars, METH_VARARGS, "print character"},
{ NULL, NULL, 0, NULL}
};
/* Module structure */
static struct PyModuleDef samplemodule = {
PyModuleDef_HEAD_INIT,
"sample",
"A sample module",
-1,
SampleMethods
};
/* Module initialization function */
PyMODINIT_FUNC
PyInit_sample2(void) {
return PyModule_Create(&samplemodule);
}
如果目标是只接受一个参数,则函数 should be declared as METH_O
,而不是 METH_VARARGS
;前者在不包装的情况下传递单个参数,后者包装在 tuple
中,需要对其进行解压缩或解析才能在其中获取 PyUnicode*
。