我有一个 C Python 扩展程序,我想打印一些诊断信息。
我正在接收一个 PyObject*
字符串。
怎样是获取此对象的字符串表示形式的规范方法,使其可用作 const char *
?
使用PyObject_Repr
(模拟 Python 的 repr
函数)或 PyObject_Str
(模拟 str
),然后调用 PyString_AsString
来获取 char *
(通常应该将其作为 const char*
使用,例如:
PyObject* objectsRepresentation = PyObject_Repr(yourObject);
const char* s = PyString_AsString(objectsRepresentation);
对于任何 PyObject
,此方法都可以使用。如果你绝对确定 yourObject
是一个Python字符串而不是其他类型的对象,比如数字,那么可以跳过第一行,直接执行:
const char* s = PyString_AsString(yourObject);
如果您正在使用Python 3,则以下是正确的答案:
static void reprint(PyObject *obj) {
PyObject* repr = PyObject_Repr(obj);
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
const char *bytes = PyBytes_AS_STRING(str);
printf("REPR: %s\n", bytes);
Py_XDECREF(repr);
Py_XDECREF(str);
}
PyObject
是普通的 Python 字符串,我该如何将其转换为 const char*
? - MontrealPyObject_Repr
在您的字符串周围放置单引号。 - IDDQDPyObject_Repr
。为了安全起见,您可以使用 if(!PyUnicode_CheckExact(obj)){...}
来验证 PyObject *obj
是否确实是 PyUnicode_Type
。 - IDDQD如果您需要在Python 3中只是打印对象,您可以使用以下其中之一的函数:
static void print_str(PyObject *o)
{
PyObject_Print(o, stdout, Py_PRINT_RAW);
}
static void print_repr(PyObject *o)
{
PyObject_Print(o, stdout, 0);
}
PyObject_Repr
(模仿 Python 的 repr
)或 PyObject_Str
(模仿 Python 的 str
)函数。对于 Python >=3.3:
char* str = PyUnicode_1BYTE_DATA(py_object);
是的,这是一个非const指针,你可以通过它可能修改(不可变)字符串。
PyObject*
,首先调用PyObject_Repr()
或PyObject_Str()
来获取一个PyUnicode*
对象。PyUnicode_AsUTF8AndSize
。除了你想要的Python字符串外,该函数还接受一个可选地址以存储长度。const char*
本身通常是指向以null结尾的C字符串的指针。将Python字符串转换为C字符串可能会导致信息丢失。因此,所有其他Python C-API函数如果从字符串返回const char*
则不建议使用。size
参数设置为NULL
。例如,PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);
printf("As const char*, ignoring length: %s\n",
PyUnicode_AsUTF8AndSize(foo, NULL));
打印
As const char*, ignoring length: foo
但是你也可以传递一个size
变量的地址,与const char*
一起使用,以确保你获取整个字符串。
PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);
printf("Including size: ");
size_t size;
const char* data = PyUnicode_AsUTF8AndSize(foo, &size);
fwrite(data, sizeof(data[0]), size, stdout);
putchar('\n');
$ ./main | cat -v
Including size: foo^@bar
PyObject *module_name; PyUnicode_AsUTF8(module_name)
PyObject *module_name; PyUnicode_AsUTF8(module_name)
Py_DECREF(objectsRepresentation)
,因为PyObject_Repr()
返回一个新的引用! - Steve