【问题标题】:How to convert an NSDictionary to a Python dict?如何将 NSDictionary 转换为 Python 字典?
【发布时间】:2009-09-19 21:47:03
【问题描述】:

我有一个使用 PyObjC 完全用 Python 编写的插件,我需要将其核心类转换为 Objective-C。其中一个基本上只是加载一个 Python 模块并执行一个特定的函数,并传递给它关键字参数。在 PyObjC 中,这是非常极端的。

但是,我很难弄清楚如何使用 Python C API 来做同样的事情。特别是,我不确定如何最好地将 NSDictionary(可能包含整数、字符串、布尔值或以上所有内容)转换为一种格式,然后我可以将其作为关键字参数传递给 Python。

有人对如何完成这样的事情有指导吗?提前致谢!

编辑:澄清一下,我正在将我现有的类(以前是 Python)转换为 Objective-C,并且无法弄清楚如何从 Objective-C 中的 NSDictionary 迁移到当我调用剩余的 Python 脚本时,我可以传递 Python 字典。 Objective-C 类基本上只是一个 Python 加载器,但我不熟悉 Python C API,并且无法确定在哪里可以找到对我有帮助的示例或函数。

【问题讨论】:

  • 我有点惊讶你不能只通过 PyObjC 将 NSDictionary 传递给 Python,然后像普通的 Python 字典一样对待它。有什么具体的东西不起作用吗?
  • 可能只是我对如何做到这一点的了解;愿意分享一个代码示例,说明如何使用 PyObjC 从 Objective-C 类中调用 Python 函数并将其传递给 NSDictionary? PyObjC 的 C API 文档也很棒;看了但什么也找不到。
  • 其实不需要代码;我没有注意到迈克尔在下面第二次回答了我!哎呀。 :-)

标签: python objective-c pyobjc


【解决方案1】:

哦,看来我误解了你的问题。好吧,走另一个方向并没有太大的不同。这应该是您正在寻找的功能(至少是一个开始)(虽然我还没有彻底测试过,所以要小心这些错误):

// 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 Reference manual,您可能还想看看。

【讨论】:

  • 谢谢迈克尔!在发布问题之前,我查看了 C API,但我无法弄清楚如何将 PyDict 方法与 Objective-C NS 对象一起使用(仍然在清理我的 C;我不得不考虑指针等已经有一段时间了向前)。感谢您的起始代码!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2016-02-01
  • 2013-06-06
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 2013-02-19
相关资源
最近更新 更多