考虑以下:
PyObject* fmt = PyUnicode_FromString("{0!r}");
PyObject* tup = PyTuple_New(2);
PyTuple_SetItem(tup, 0, PyUnicode_FromString("hello"));
PyTuple_SetItem(tup, 1, PyUnicode_FromString("world"));
PyObject* formatted = PyObject_CallMethod(fmt, "format", "O", tup);
PyObject* bytes = PyUnicode_AsEncodedString(formatted, "UTF-8", "strict");
printf(PyBytes_AS_STRING(bytes));
我希望它像这个 python 代码一样:
>>> u'{0!r}'.format((u"hello", u"world"))
"(u'hello', u'world')"
但是我的输出很简单:
u'hello'
我可以想象它实际上是在调用函数,如:
>>> u'{0!r}'.format(u"hello", u"world")
u'hello'
我在找什么:
最佳答案
问题似乎与 Py_BuildValue
的工作方式有关(似乎被 PyObject_CallMethod
使用)。来自 docs(强调我的):
这意味着不是将带有 "O"
的格式字符串 tup
构建为 args=(tup,)
并调用 fmt.format(*args)
(扩展为 fmt.format(("hello", "world"))
),而是构建 args=tup
,因此 fmt.format(*args)
扩展为 fmt.format("hello", "world")
,如您所想。解决方案也在 docs 中:
所以,只需改变:
PyObject* formatted = PyObject_CallMethod(fmt, "format", "O", tup);
至:PyObject* formatted = PyObject_CallMethod(fmt, "format", "(O)", tup);
你会得到 ('hello', 'world')
的期望输出。完整代码片段(使用 gcc thissnippet.c -I /usr/include/python3.4m/ -l python3.4m
编译):#include <Python.h>
int main() {
Py_Initialize();
PyObject* fmt = PyUnicode_FromString("{0!r}");
PyObject* tup = PyTuple_New(2);
PyTuple_SetItem(tup, 0, PyUnicode_FromString("hello"));
PyTuple_SetItem(tup, 1, PyUnicode_FromString("world"));
PyObject* formatted = PyObject_CallMethod(fmt, "format", "(O)", tup);
PyObject* bytes = PyUnicode_AsEncodedString(formatted, "UTF-8", "strict");
printf(PyBytes_AS_STRING(bytes));
Py_Finalize();
}
关于python - 使用单个元组调用 PyObject_CallMethod 解包参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28267535/