Re: Need advice/help with embedding python in a C program

Guido.van.Rossum@cwi.nl
Fri, 18 Mar 1994 10:23:52 +0100

> This is a numerical simulation that has several dozen subroutines with
> hundreds of input variables. The user only needs to explicitly set the
> input variables that are changed from their default values. At the
> beginning of a simulation run, each subroutine requiring input would have an
> initialization section for each input variable. I will express the
> functionality of what I think I want with the following pseudo-code:
> sub1(){
> ...
> /* initialize variables from python parser*/
> x = py_is_var_defined("sub1_x") ? py_get_var_value("sub1_x") :
> x_default_value;
> ...
> }
> The input parsed by python would be normal python code with the variables of
> interest defined and a call to the function that runs the simulation. After
> completion of the simulation run, control would return to the python parser.

Sounds like you are suggesting the following kind of interface to call
your simulation from Python (0):

>>> sub_1 = 45
>>> sub_7 = 1000
>>> run_simulation()
>>> sun_7 = 2000
>>> run_simulation()

In general it's a bad idea to use the global name space for input to a
specific function. There are two alternatives: (1) put the variables
in a dictionary and pass that dictionary to the simulation; (2) put
the variables in a module specific to the simulation.

For example, (1) would look like:

>>> d = {'sub_1': 45, 'sub_7': 1000}
>>> run_simulation(d)
>>> d['sub_7'] = 2000
>>> run_simulation(d)

and (2) would look like

>>> import sim
>>> sim.sub_1 = 45
>>> sim.sub_7 = 1000
>>> sim.run_simulation()
>>> sim.sub_7 = 2000
>>> sim.run_simulation()

One advantage of (2) would be that you can set all variables in the
module to their default values so the user can not only inspect but
also set the default values. It is also a more "python-ish" solution.
A disadvantage may be that it will be more difficult for the user to
maintain separate sets of values, which is easily accomplished using
(1) -- but maybe you're not interested in that anyway.

Back to your question of how to access the value: for (0) you would
have to do something like

object *modules = sysget("modules");
object *mod = dictlookup(modules, "__main__");
object *dict = getmoduledict(mod);
object *sub_1 = dictlookup(dict, "sub_1");
if (sub_1 != NULL)
x = getintvalue(sub_1);
else
x = x_default_value;

(NB ALL error checking left out of the above. No reference counts are
incremented by these calls.)

For (1) you could do the final dictlookup() call on the argument
passed into the run_simulation() function.

For (2) you could replace "__main__" with "sim" or you could save a
pointer to the module dictionary when you initialize it.

One final hint: the functions mentioned here are undocumented, but
that doesn't mean you are not supposed to use them -- it merely means
that the documentation for Python's internals is incomplete. Have a
look at the source code (also at that of other extension modules!) to
find out what kind of functions are available and how to use them!

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
URL: <http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>