2009-09-19 1 views
2

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

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

У кого-нибудь есть указатели на то, как выполнить что-то подобное? Заранее спасибо!

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

+0

Я немного удивлен, что вы не можете просто передать NSDictionary в Python через PyObjC, а затем рассматривать его как обычный словарь python. Есть ли что-то конкретное, что не работает? – bbum

+0

Наверное, только мои знания о том, как это сделать; поделитесь примером кода, как использовать PyObjC для вызова функции Python из класса Objective-C и передать ему NSDictionary? Документация API C для PyObjC также была бы большой; смотрел, но ничего не мог найти. –

+0

На самом деле, код не требуется; Я не заметил, что Майкл ответил мне второй раз ниже! Упс. :-) –

ответ

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 Reference manual если вы еще этого не сделали.

+0

Спасибо, Майкл! Я просмотрел API C, прежде чем я разместил вопрос, но я не мог понять, как использовать методы PyDict с объектами Objective-C NS (все еще пытаясь покинуть мой C, было некоторое время, так как мне приходилось думать о указателях и так далее д). Спасибо за стартовый код! –