Я писал функцию расширения C, которая должна была принять объект str
в качестве аргумента. Код показан ниже:python3 str объект не может пройти PyUnicode_Check
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
Насколько я знаю, Python 3-ые годы str()
тип называется PyUnicode в C, а код C, описанный выше, написан в разделе «python cookbook3» Char15.13. Я просто не могу решить проблему. Может кто-нибудь сказать мне, что не так с моим кодом.
Вот что «питон 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);
}
Вам не нужен 'PyArg_ParseTuple' с аргументом' u' first? Но это зависит от типов аргументов в таблице методов (например, METH_VARARGS), которые вы не указали. – cdarke
Да, factuallty, PyArg_parseTupel может решить эту проблему отлично. Но в «python cookbook3» говорится, что есть еще одна тренировка без использования PyArg_ParseTuple. – sun
Я не думал, что какая-либо часть кода может пойти не так, потому что она хорошо работает для других функций. Я добавляю весь код в описание вопроса. – sun