考虑以下:

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/

    10-13 07:22