2009-09-19 5 views
2

J'ai un plugin écrit entièrement en Python en utilisant PyObjC dont j'ai besoin de convertir les classes de base en Objective-C. L'un d'entre eux charge simplement un module Python et exécute une fonction spécifique en lui passant les arguments de mots-clés. Dans PyObjC, c'était extrêmement.Comment convertir un dictionnaire NSDictionary en dict Python?

Cependant, j'ai du mal à comprendre comment faire la même chose avec l'API C de Python. En particulier, je ne suis pas sûr de la meilleure façon de convertir un NSDictionary (qui peut contenir des entiers, des chaînes, des booléens, ou tout ce qui précède) dans un format que je peux ensuite transmettre à Python en tant qu'argument mot-clé.

Quelqu'un at-il des indications sur la façon d'accomplir quelque chose comme ça? Merci d'avance!

Modifier: juste pour clarifier, je convertir ma classe existante qui était autrefois Python en Objective-C, et je suis de la difficulté à trouver comment passer d'un NSDictionary en Objective-C à un dictionnaire Python je peux transmettre lorsque j'appelle les scripts Python restants. La classe Objective-C est essentiellement un chargeur Python, mais je ne suis pas familier avec l'API Python C et je n'arrive pas à trouver des exemples ou des fonctions qui pourraient m'aider.

+0

Je suis un peu surpris que vous ne pouvez pas simplement passer le NSDictionary en Python via PyObjC et ensuite le traiter comme un dictionnaire python régulier. Y at-il quelque chose de spécifique qui ne fonctionne pas? – bbum

+0

Probablement juste ma connaissance de la façon de le faire; Prenez soin de partager un exemple de code sur la façon d'utiliser PyObjC pour invoquer une fonction Python depuis une classe Objective-C et lui passer un NSDictionary. La documentation d'une API C pour PyObjC serait géniale aussi; regardé mais ne pouvait rien trouver. –

+0

En fait, aucun code n'est nécessaire; Je n'ai pas remarqué que Michael m'a répondu une deuxième fois ci-dessous! Oups. :-) –

Répondre

2

Oh, on dirait que j'ai mal compris votre question. Eh bien, aller dans l'autre sens n'est pas très différent. Cela devrait être (comme moins un début de) la fonction que vous recherchez (je ne l'ai pas testé à fond, donc méfiez-vous des bugs):

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

Vous pouvez également jeter un oeil à le Python/C API Reference manual si vous ne l'avez pas déjà fait.

+0

Merci Michael! J'ai regardé à travers l'API C avant de poster la question, mais je n'arrivais pas à comprendre comment tirer parti des méthodes PyDict avec les objets Objective-C NS (dépoussiérer mon C pendant un certain temps car je devais penser aux pointeurs et ainsi avant). Merci pour le code de départ! –

Questions connexes