我在C中创建了一个Python扩展,因为它具有友好的结构和高效的用法。因此,对于某些繁重的操作有很多源代码应该在C中。并且引用了许多内部字段。
现在,我将进行一些美学改进:主要是tp_repr
和tp_str
位置。我必须用C做吗?我认为在Python中使用它们应该很容易,但用C编写它似乎是一场噩梦并且毫无用处。
我有内部字段,如编码二进制字符串,字典等。使用Python功能似乎很简单:
def repr_func(obj):
return "MyObject(name='%s'.encode('utf-16-be'), id=%d, map=%s)"
% (obj.name.decode("utf-16-be"), obj.id, repr(obj.map))
我知道我可以在C中做到这一点,但在Python中做这件事似乎更清晰。我不需要性能,那些将用于调试和测试,所以我需要它们有用和干净。
如果没有C源的深层变化,有没有办法做到这一点?
答案 0 :(得分:2)
在编程中经常这样,有不同的方法可以完成任务。
您在Python中所做的事情,可以通过类似
之类的东西在C(Pyhton 2. *)中实现static PyObject * repr (Obj *self) {
PyObject *map = PyObject_Repr(self->map);
if (!map) return NULL;
char *map_repr = PyString_AsString(map);
PyObject *repr = PyString_FromFormat(
"MyObject(name='%s'.encode('utf-16-be'), id=%d, map=%s)",
self->name, self->id, map_repr);
Py_DECREF(map);
return repr;
}
并假设您的对象的typedef为Obj
且名称为char *
。如果是PyObeject *
,您可以使用PyString_AsDecodedObject
进行解码。在Python 3. *中,您可能需要使用PyUnicode_*
或PyBytes_*
函数。
如果你想使用纯Python中定义的函数,你可以通过导入模块来实现,它定义了这些函数,如
static PyObject * repr (Obj *self) {
PyObject *module = PyImport_ImportModule("repr_mod");
if (!module) return NULL;
PyObject *repr = PyObject_CallMethod(module, "repr_func", "(O)", self);
Py_DECREF(module);
return repr;
}
其中repr_mod
是模块的名称。
最后,您只需在初始化类型时将tp_repr
设置为(reprfunc) repr
。
我不会考虑C源的深层变化,所以也许只是你正在寻找的东西。