8

Using PyObjC, is it possible to import a Python module, call a function and get the result as (say) a NSString?

For example, doing the equivalent of the following Python code:

import mymodule
result = mymodule.mymethod()

..in pseudo-ObjC:

PyModule *mypymod = [PyImport module:@"mymodule"];
NSString *result = [[mypymod getattr:"mymethod"] call:@"mymethod"];
2
  • Duplicate: stackoverflow.com/questions/49137/…; stackoverflow.com/questions/297112/…. You can embed Python in any application. Commented Apr 26, 2009 at 1:56
  • 2
    @S.Lott This isn't a duplicate; those questions are about C++, not Objective-C. While you can use Objective-C++ to mix C++ and Objective-C, you'd have to wrap all of the C++ code in Objective-C classes yourself if you need to use them as Objective-C classes. Commented Apr 26, 2009 at 2:36

2 Answers 2

12

As mentioned in Alex Martelli's answer (although the link in the mailing-list message was broken, it should be https://docs.python.org/extending/embedding.html#pure-embedding).. The C way of calling..

print urllib.urlopen("http://google.com").read()
  • Add the Python.framework to your project (Right click External Frameworks.., Add > Existing Frameworks. The framework in in /System/Library/Frameworks/
  • Add /System/Library/Frameworks/Python.framework/Headers to your "Header Search Path" (Project > Edit Project Settings)

The following code should work (although it's probably not the best code ever written..)

#include <Python.h>

int main(){
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Py_Initialize();

    // import urllib
    PyObject *mymodule = PyImport_Import(PyString_FromString("urllib"));
    // thefunc = urllib.urlopen
    PyObject *thefunc = PyObject_GetAttrString(mymodule, "urlopen");

    // if callable(thefunc):
    if(thefunc && PyCallable_Check(thefunc)){
        // theargs = ()
        PyObject *theargs = PyTuple_New(1);

        // theargs[0] = "http://google.com"
        PyTuple_SetItem(theargs, 0, PyString_FromString("http://google.com"));

        // f = thefunc.__call__(*theargs)
        PyObject *f = PyObject_CallObject(thefunc, theargs);

        // read = f.read
        PyObject *read = PyObject_GetAttrString(f, "read");

        // result = read.__call__()
        PyObject *result = PyObject_CallObject(read, NULL);


        if(result != NULL){
            // print result
            printf("Result of call: %s", PyString_AsString(result));
        }
    }
    [pool release];
}

Also this tutorial is good

Sign up to request clarification or add additional context in comments.

Comments

3

Not quite, AFAIK, but you can do it "the C way", as suggested for example in http://lists.apple.com/archives/Cocoa-dev/2004/Jan/msg00598.html -- or "the Pyobjc way" as per http://osdir.com/ml/python.pyobjc.devel/2005-06/msg00019.html (see also all other messages on that thread for further clarification).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.