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

可以在Python扩展对象中使用宽字符成员吗?,python,c,unicode,python-extensions,Python,C,Unicode,Python Extensions,使用PyMemberDef声明中的T_字符串定义,在Python C扩展中为一个基类型为char*的对象创建一个成员非常简单 为什么wchar\u t*似乎没有等价物?如果真的有,那是什么 e、 g struct对象包含char*文本 PyMemberDef数组具有{“text”,T_字符串,offsetof(struct object,text),只读,“这是一个普通字符串。”} 对像这样的东西 struct对象包含wchar\u t*wtext PyMemberDef数组具有{“wtext”

使用
PyMemberDef
声明中的
T_字符串定义,在Python C扩展中为一个基类型为
char*
的对象创建一个成员非常简单

为什么
wchar\u t*
似乎没有等价物?如果真的有,那是什么

e、 g

struct对象
包含
char*文本

PyMemberDef
数组具有
{“text”,T_字符串,offsetof(struct object,text),只读,“这是一个普通字符串。”}

对像这样的东西

struct对象
包含
wchar\u t*wtext

PyMemberDef
数组具有
{“wtext”,twstring,offsetof(struct object,wtext),READONLY,“这是一个宽字符串”}


我知道类似于
PyUnicode\u AsString()
及其相关方法可用于将数据编码为UTF-8,存储在基本字符字符串中,然后解码,但这样做需要将泛型的
getattr
setattr
方法/函数包装为用于编码文本的方法/函数,而且,当您希望在结构中使用固定元素大小的字符数组,并且不希望存储在其中的有效字符数发生变化时,它不是非常有用。

直接使用
wchar\t
是不可移植的。相反,Python将定义为Unicode字符的存储单元

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

对于您的用例,您的对象可以使用
T\u 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\u 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]
    ...
inti=0;
Py_ssize_t size=PyUnicode_GetSize(self->wtext);
Py_UNICODE*chars=PyUnicode_AS_UNICODE(self->wtext);
对于(i=0;i
我不知道这是否回答了您的问题,但是:根据Python的编译方式,Py_UNICODE可能是wchar_t。Python可以使用每个UNICODE字符2个字节(即wchar),或4。因此C代码需要使用PyUnicode函数来处理unicode字符串,而不需要假设它们存储的格式。@Thomas:
wchar\u t
是两个或四个字节,这取决于平台。我明白了。不过,如果我没有弄错的话,Python参考文献似乎建议在
t\u对象上使用
t\u EX
由于某些情况是如何处理的。是的,您可以使用
T\u OBJECT\u EX
来代替。对于
READONLY
属性(不能删除)
T_对象
也应该可以正常工作。选择还取决于您是希望
self->wtext
NULL
值引发错误,还是只返回
None
,这实际上取决于您希望对象显示的行为。