Python CAPI:如何在ObjectiveC中使用返回的Python字典?

2024-09-24 22:30:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我的Python脚本app.py具有以下函数,例如:

def testmethod(x):
    return {"steps":["hello","world"]}

我在Objective-C中使用Python C-API如下:

^{pr2}$

在这之后,我真的不确定如何转换myResult来检索我的字典。对于双精度和字符串,我们通常使用PyFloat_AsDoublePyUnicode_AsUTF8StringPyBytes_AsString函数,但我似乎找不到{}或等效方法。在

double result = PyFloat_AsDouble(myResult);
NSLog(@"Result: %f",result);*/

PyObject* pStrObj = PyUnicode_AsUTF8String(myResult);
char* zStr = PyBytes_AsString(pStrObj);
NSLog(@"String: %@",[NSString stringWithUTF8String:zStr]);

我对Objective-C没有太多的经验,所以可能我找的地方不对。在

有人能帮我弄清楚如何将PyObject转换成NSDictionary吗?在

我基本上是在寻找一种先访问字典(例如map)的C方法,然后使用Objective-C方法将其转换为NSDictionary。与我如何使用PyUnicode_AsUTF8String、PyBytes_AsString和stringWithUTF8String组合在一起,从Python字符串中获取NSString。为字典找相似的东西。在

我已经想出了一个办法来达到这个目的,但我不知道这是否是最好的办法。我修改了python脚本,使用json.dumps返回字典的字符串表示。然后在myObjective C代码中,我首先获取字符串,然后使用JSONObjectWithData将json字符串转换为NSDictionary。目前这是可行的,但我很好奇是否有更好的方法来实现这一点,而不必从Python返回string而不是dictionary。对我来说,这更像是一个解决办法。我现在的情况是:

应用程序副本:

import json
def testmethod(x):
    return json.dumps({"steps":["hello","world"]})

目标C:

Py_Initialize();
PyObject *pName = PyUnicode_DecodeFSDefault("app");
PyObject* pModule = PyImport_Import(pName);
Py_DECREF(pName);

PyObject* myFunction = PyObject_GetAttrString(pModule,(char*)"testmethod");
PyObject* args = PyTuple_Pack(1,PyFloat_FromDouble(223.22));
PyObject* myResult = PyObject_CallObject(myFunction, args);

PyObject* pStrObj = PyUnicode_AsUTF8String(myResult);
char* zStr = PyBytes_AsString(pStrObj);
NSString *jsonStr = [NSString stringWithUTF8String:zStr];
NSLog(@"String: %@",jsonStr);

NSError *error;
NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

NSLog(@"Dictionary: %@",dictionary);

Tags: 方法字符串json字典pyobjectpyunicodensstringmyresult
1条回答
网友
1楼 · 发布于 2024-09-24 22:30:19

使用^{}迭代字典的键/值对。在

如果仍要使用PyObject*s,还应提供Python哈希和相等函数。否则,应尝试将它们强制为本机类型。在

(这是伪代码,因为我并不真正了解Objective-C,但使用过C-Api和Python)

NSObject* convert_py_object(PyObject* obj) {
    if (PyDict_Check(obj)) return convert_py_dict(obj);
    if (PyLong_Check(obj)) return convert_py_int(obj);
    if (PyUnicode_Check(obj)) return convert_py_str(obj);
    if (PyBytes_Check(obj)) return convert_py_bytes(obj);
    if (PyList_Check(obj) || PyTuple_Check(obj) || PyIter_Check(obj)) return convert_py_list(obj);
    throw error;
}

NSDictionary* convert_py_dict(PyObject* dict) {
    if (!PyDict_Check(dict)) throw error;
    NSDictionary* native_dict;
    PyObject *key;
    PyObject *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        native_dict[convert_py_object(key)] = convert_py_object(value);
    }
    return native_dict;
}

另一种选择是只使用pythonapi访问字典的值。因此,使用PyDict_NextPyDict_GetItemString迭代所有值,以使用简单的char *s访问字符串项,PyDict_GetItem来访问任意Python值。在

相关问题 更多 >