Theory

The Python interpreter is usually accessed in everyday scripting work through an interactive command line shell. The Python/C API exposes that interface in a series of functions, but the most interesting to us is py_run_simple_string:

Example 8-1. The py_run_simple_string short form

py_run_simple_string (command: STRING): INTEGER

This function takes a string containing the text to interpret and simple executes the commands as if they had just been typed into the Python interpreter. This can be extremely handy for high-level use of Python--simple use py_run_simple_string to import libraries, print messages, or do any high level activity. The function returns -1 to indicate an error status on the execution.

While this is somewhat useful, we can get more mileage out of the interpreter by using it as a supplementary constructor. For example, our previous example program constructed a dictionary using a default constructor and a series of set_item_string calls, as well as temporary PYTHON_OBJECTs created by a PYTHON_OBJECT_FACTORY:

Example 8-2. The by-hand method of constructing the Python dictionary { "a" : "Hello", "b" : "World" }

create a.make
a.set_item_string( "b", python_object_factory.new_python_string( "World!" ) )
a.set_item_string( "a", python_object_factory.new_python_string( "Hello" ) )

It would seem that the Python interpreter might be a better way to do this, and it is. The PYTHON_CLIENT.py_run_string is somewhat more complex, but offers the benefit of returning a Python object pointer-- and as such can be used to not just run code, but evaluate it and return the results of such an evaluation:

Example 8-3. The py_run_string function

py_run_string (str: STRING; start: INTEGER; globals: POINTER; locals: POINTER ) : POINTER

However, py_run_string does have some problems. Most significantly, it really requires more inputs than it generally needs; start, for example, specifies the start of evaluation; globals and locals specify the global and local environment. All most of us need to use is str, so we placed a more easy-to-use variant in PYTHON_CLIENT:

Example 8-4. The evaluated_expression function

evaluated_expression( expr : STRING ) : PYTHON_OBJECT
   -- evaluates an expression

This helper function does exactly what one would expect--evaluates the expression expr and returns the result in a new PYTHON_OBJECT. Using evaluated_expression, the above dictionary creation could be done thusly:

Example 8-5. Using the Python interpreter to make the dictionary { "a" : "Hello", "b" : "World" }

create a.make_from_python_object( evaluated_expression( "{ 'a' : 'Hello', 'b' : 'World' } ) )

By using these two primary commands (py_run_string and evaluated_expression), developers can get a fair amount of expressiveness without the overhead of repeated member function calls.