如何将NSDictionary转换为Python字典?

2 投票
1 回答
1919 浏览
提问于 2025-04-15 14:26

我有一个完全用Python写的插件,使用了PyObjC,现在我需要把它的核心类转换成Objective-C。其中一个类基本上就是加载一个Python模块并执行一个特定的函数,同时传递一些关键字参数。在PyObjC中,这个过程非常简单。

不过,我现在在用Python的C API做同样的事情时遇到了困难。特别是,我不太确定如何把一个NSDictionary(它可能包含整数、字符串、布尔值,或者这些的组合)转换成一个可以传递给Python的格式,以便作为关键字参数使用。

有没有人能给我一些建议,告诉我怎么做到这一点?提前谢谢!

编辑:为了更清楚,我是在把我之前的Python类转换成Objective-C,现在在从Objective-C的NSDictionary转换成Python字典时遇到了麻烦,这样我才能在调用剩下的Python脚本时传递它。这个Objective-C类基本上就是一个Python加载器,但我对Python的C API不太熟悉,不知道该去哪里找示例或函数来帮助我。

1 个回答

2

哦,看起来我误解了你的问题。其实,反过来做也不是特别复杂。这应该是你想要的函数的一个起始版本(不过我没有彻底测试过,所以可能会有一些小问题):

// Returns a new reference
PyObject *ObjcToPyObject(id object)
{
    if (object == nil) {
        // This technically doesn't need to be an extra case, 
        // but you may want to differentiate it for error checking
        return NULL;
    } else if ([object isKindOfClass:[NSString class]]) {
        return PyString_FromString([object UTF8String]);
    } else if ([object isKindOfClass:[NSNumber class]]) {
        // You could probably do some extra checking here if you need to
        // with the -objCType method.
        return PyLong_FromLong([object longValue]);
    } else if ([object isKindOfClass:[NSArray class]]) {
        // You may want to differentiate between NSArray (analagous to tuples) 
        // and NSMutableArray (analagous to lists) here.
        Py_ssize_t i, len = [object count];
        PyObject *list = PyList_New(len);
        for (i = 0; i < len; ++i) {
            PyObject *item = ObjcToPyObject([object objectAtIndex:i]);
            NSCAssert(item != NULL, @"Can't add NULL item to Python List");
            // Note that PyList_SetItem() "steals" the reference to the passed item.
            // (i.e., you do not need to release it)
            PyList_SetItem(list, i, item);
        }
        return list;
    } else if ([object isKindOfClass:[NSDictionary class]]) {
        PyObject *dict = PyDict_New();
        for (id key in object) {
            PyObject *pyKey = ObjcToPyObject(key);
            NSCAssert(pyKey != NULL, @"Can't add NULL key to Python Dictionary");
            PyObject *pyItem = ObjcToPyObject([object objectForKey:key]);
            NSCAssert(pyItem != NULL, @"Can't add NULL item to Python Dictionary");
            PyDict_SetItem(dict, pyKey, pyItem);
            Py_DECREF(pyKey);
            Py_DECREF(pyItem);
        }
        return dict;
    } else {
        NSLog(@"ObjcToPyObject() could not convert Obj-C object to PyObject.");
        return NULL;
    }
}

如果你还没看过的话,建议你去看看这个Python/C API参考手册

撰写回答