Как преобразовать NSDictionary в Python dict? - PullRequest
2 голосов
/ 20 сентября 2009

У меня есть плагин, написанный полностью на Python с использованием PyObjC, основные классы которого мне нужно преобразовать в Objective-C. Один из них в основном просто загружает модуль Python и выполняет определенную функцию, передавая ему ключевые аргументы. В PyObjC это было чрезвычайно.

Однако мне сложно понять, как сделать то же самое с помощью Python C API. В частности, я не уверен, как лучше преобразовать NSDictionary (который может содержать целые числа, строки, логические значения или все вышеперечисленное) в формат, который я затем могу передать Python в качестве аргументов ключевого слова.

У кого-нибудь есть указания, как этого добиться? Заранее спасибо!

Редактировать : просто чтобы уточнить, я конвертирую свой существующий класс, который раньше был Python, в Objective-C, и у меня возникают проблемы с выяснением, как перейти от NSDictionary в Objective-C к Python словарь, который я могу передать, когда вызову оставшиеся скрипты Python. Класс Objective-C в основном просто загрузчик Python, но я незнаком с API-интерфейсом Python C и не могу понять, где искать примеры или функции, которые мне помогут.

1 Ответ

2 голосов
/ 20 сентября 2009

О, похоже, я неправильно понял ваш вопрос. Ну, идти в другом направлении не сильно отличается. Это должна быть (как минимум, начало) функция, которую вы ищете (хотя я не проверил ее полностью, так что остерегайтесь ошибок):

// 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;
    }
}

Возможно, вы захотите взглянуть на Справочное руководство по API Python / C , если вы этого еще не сделали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...