2013-08-21 2 views
0

Учитывая строку формата и словарь, которые хранятся в переменных PyObject*, как я могу позвонить str.format_map из C API, используя эти значения?Вызов str.format_map из C API

Моей цели здесь, чтобы сделать эквивалент:

# Given the "dict" and "fmt" are already in PyObject* 
dict = {'Foo': 54.23345} 
fmt = "Foo = {Foo:.3f}" 

# How do I get result? 
result = fmt.format_map(dict) 
+0

Помимо очевидной последовательности 'PyObject_GetAttr', создания 1-кортежа,' PyObject_Call'? – delnan

+0

@delnan Почему здесь нужен 'PyObject_GetAttr'? –

+0

Я просто предположил, что реализация 'format_map' является' static' или иначе внутренней, поэтому вам придется получить ее из объекта 'fmt' (или объекта типа str, если у вас есть причина). – delnan

ответ

1

Что-то вроде этого фрагмента должен хватить:

PyObject *dict, *value, *result, *fmt; 
dict = PyDict_New(); 
if (!dict) 
    return NULL; 
value = PyFloat_FromDouble(54.23345); 
if (!value) { 
    PY_DECREF(dict); 
    return NULL; 
} 
if (PyDict_SetItemString(dict, "Foo", value) < 0) { 
    Py_DECREF(value); 
    Py_DECREF(dict); 
    return NULL; 
} 
Py_DECREF(value); 
fmt = PyUnicode_FromString("Foo = {Foo:.3f}"); 
if (!fmt) { 
    Py_DECREF(dict); 
    return NULL; 
} 
result = PyObject_CallMethodObjArgs(fmt, "format_map", dict, NULL); 
Py_DECREF(fmt); 
Py_DECREF(dict); 
return result; 

Как вы можете видеть, это громоздко, так что лучше сделать, как насколько это возможно в Python!

+0

В Python 3 единственным изменением будет создание 'PyObject *' для '' format_map'', правильно? –

+0

Нет, на самом деле я намеревался этот код работать на Python 3. –

+0

В этом случае это не компилируется ... 'PyObject_CallMethodObjArgs' берет' PyObject * 'для второго arg, а не' const char * '- http://docs.python.org/3.3/c-api/object.html –