Dpulicating "class Foo:" in C

Mark Charsley mark.charsley at REMOVE_THIS.radioscape.com
Fri Jul 19 07:15:00 EDT 2002


First let me point out, this is _not_ asking how to wrap up C functions in 
a python class. I'm using the boost::python stuff to do that with no 
troubles at all.

I'm working on a C++ program where we're using python as an expression 
parser. We've got a whole bunch of variables and associated expressions 
that we read in from a file at run time. So for instance we might have a 
variable called "Foo" and an associated expression 

	"spam * grumby + parrot". 

"Spam" "Grumby" and "Parrot" would be other variables and have their own 
expressions.  We've had the system working lovely - all the input 
variables would have an associated Python object (created with 
PyDict_SetItemString) set to a value, and all the output variables would 
have an associated Python Expression Object (created with 
Py_CompileString), and we could set input variables and evaluate output 
variables fine.

The problem came when The Powers That Be decreed that the expressions 
could be of the form 

	"spam * grumby + Configure.parrot"
	
Configure being a sort of namespace - it's name was fixed, but its 
contents was not. A quick bit of experimenting revealed that we could hack 
up namespaces with the following python...

	class Configure:
		pass
	
and then we could add arbitrary variables to it, as below:

	Configure.parrot = "dead"
	Configure.spam = "spam, spam, spam"
	Configure.NumberOfChiefWeapons = 2
	Configure.NumberOfChiefWeapons = 3
	Configure.NumberOfChiefWeapons = 4

Alas after two days of experimentation, I can't find a way to replicate 
the above python from C. I'm currently having to call 


	PyRun_String("class Configure:\n"
                          "    pass\n",
                          Py_file_input, mDict, mDict);

during my C++ object's initialisation, and then

	PyObject* Value = GetValueFromSnippedCode();
	
        char* temp_name = "temp_var_39C22D08_D340_458a";
	PyDict_SetItemString(mDict, temp_name, Value);

        m_ctxt.SetVariable(temp_name,value);
        std::string expr("Configure.");
        expr += m_xml.GetName();
        expr += " = ";
        expr += temp_name;

	PyRun_String(expr.c_str(), Py_eval_input, mDict, mDict);


Which works but is rather inelegant, and far from efficient. Every attempt 
I've made to work out how to replace the above calls to PyRun_String with 
direct calls to the C API have ended in miserable failure (well Access 
Violations and/or "foo is not a member of Configure"-style error 
messages). I was also a bit puzzled not to find any PyClass_* functions in 
the API: what exactly is a Python class (it seems to be some sort of 
Dictionary, but I can't work out how to create one)?

Many TIA

-- 

Mark - personal opinion only, could well be wrong, not representing 
company, don't sue us etc. etc.



More information about the Python-list mailing list