可以在Python扩展对象中使用宽字符成员吗?

时间:2011-05-31 20:25:31

标签: python c unicode python-extensions

使用char *声明中的T_STRING定义,在基类型为PyMemberDef的Python C扩展中为对象创建成员很简单。

为什么似乎没有wchar_t *的等价物?如果确实存在,那是什么?

e.g。

struct object包含char *text

PyMemberDef数组有{"text", T_STRING, offsetof(struct object, text), READONLY, "This is a normal character string."}

之类的东西相比

struct object包含wchar_t *wtext

PyMemberDef数组有{"wtext", T_WSTRING, offsetof(struct object, wtext), READONLY, "This is a wide character string"}

我理解像PyUnicode_AsString()及其相关方法这样的东西可以用来编码UTF-8中的数据,将它存储在一个基本的字符串中,然后解码,但这样做就需要包装泛型getattrsetattr方法/函数与记录编码文本的方法/函数,当你想要一个结构中固定元素大小的字符数组并且不想要有效数字时它不是很有用可以存储在其中的字符可以改变。

1 个答案:

答案 0 :(得分:2)

直接使用wchar_t不可移植。相反,Python将Py_UNICODE type定义为Unicode字符的存储单元。

根据平台的不同,Py_UNICODE可定义为wchar_t(如果可用),或无符号短/整数/长,其宽度将根据Python的配置方式而变化(UCS2与UCS4) )和架构和C编译器使用。您可以在unicodeobject.h中找到相关定义。

对于您的用例,您的对象可以使用T_OBJECT具有Unicode字符串的属性:

static struct PyMemberDef attr_members[] = {
  { "wtext", T_OBJECT, offsetof(PyAttrObject, wtext), READONLY, "wide string"}
  ...

您可以在对象的初始值设定项中执行类型检查:

...
if (!PyUnicode_CheckExact(arg)) {
    PyErr_Format(PyExc_ValueError, "arg must be a unicode string");
    return NULL;
}
Py_INCREF(arg);
self->wtext = arg;
...

如果您需要迭代Unicode字符串中的低级字符,则会有一个返回Py_UNICODE *的宏:

int i = 0;
Py_ssize_t size = PyUnicode_GetSize(self->wtext);
Py_UNICODE *chars = PyUnicode_AS_UNICODE(self->wtext);
for (i = 0; i < size; i++) {
    // use chars[i]
    ...