import inspect, re def generate( obj ): name = obj.__name__ inst = obj() members = {} methods = {} matcher = re.compile( '^__.*__$' ) for i in inspect.getmembers(inst): str = i[0] val = i[1] if matcher.match(str) == None: if inspect.ismethod(val): methods[str] = val else: members[str] = val print 'typedef struct {\n\tPyObject_HEAD' for key in members: print "\tPyObject *" + key + ";" print '} ' + name + ";\n\n" typename = name+'Type' dealloc_name = name+'_dealloc' new_name = name+'_new' init_name = name+'_init' members_name = name + '_members' methods_name = name + '_methods' if obj.__doc__: docstr = obj.__doc__ else: docstr = '' print 'static PyObject *' print new_name + '( PyTypeObject *type, PyObject *args, PyObject *kwds )' print '{' print '\t' + name + ' *self;' print '\tself = (' + name + ' *)type->tp_alloc(type, 0);' print '\treturn (PyObject *)self;' print '}\n\n' print 'static int' print init_name + '( ' + name + ' *self, PyObject *args )' print '{\n\treturn 0;\n}\n\n' print 'static void' print dealloc_name + '( ' + name + ' *self )' print '{\n}\n\n' for method in methods: print 'static PyObject *' print name + '_' + method + '( ' + name + ' *self, PyObject *args )' print '{\n}\n\n\n' print 'static PyMethodDef ' + methods_name + '[] = {' for method in methods: if methods[method].__doc__: mdocstr = methods[method].__doc__ else: mdocstr = '' print "\t{\"" + method + '", (PyCFunction)' + name + '_' + method + ', METH_VARARGS, "' + mdocstr + '"},' print "\t{NULL}" print "};\n\n" print 'static PyMemberDef ' + members_name + '[] = {' for mem in members: if methods[method].__doc__: mdocstr = methods[method].__doc__ else: mdocstr = '' print '\t{"' + mem + '", T_OBJECT_EX, offsetof(' + name + ', ' + mem + '), 0, "' + mdocstr +'"},' print "\t{NULL}" print "};\n\n" print 'PyTypeObject '+typename + ' = {' print "\tPyObject_HEAD_INIT(0)" print "\t0,\t\t\t/*ob_size*/" print "\t\""+name+'",\t\t/*tp_name*/' print "\tsizeof(" + name + '),' print "\t0,\t\t\t/*tp_itemsize*/" print "\t(destructor)"+dealloc_name+",\t\t/*tp_dealloc*/" l = ['tp_print', 'tp_getattr', 'tp_setattr', 'tp_compare', 'tp_repr', 'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash ', 'tp_call', 'tp_str', 'tp_getattro', 'tp_setattro', 'tp_as_buffer'] for i in l: print "\t0,\t\t\t/*"+i+"*/" print "\tPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,\t/*tp_flags*/" print "\t\""+docstr+"\",\t\t\t/*tp_doc*/" l = ['tp_traverse', 'tp_clear', 'tp_richcompare', 'tp_weaklistoffset', 'tp_iter', 'tp_iternext'] for i in l: print "\t0,\t\t\t/*"+i+"*/" print "\t"+methods_name+"," print "\t"+members_name+"," l = ['tp_getset', 'tp_base', 'tp_dict', 'tp_descr_get', 'tp_descr_set', 'tp_dictoffset'] for i in l: print "\t0,\t\t\t/*"+i+"*/" print "\t(initproc)"+init_name+',' print "\t0, /* tp_alloc */" print "\t"+new_name print "};"
import gen_ext
class Nanika:
def __init__(self):
self.x = 4
self.y = 40
def nanikaMethod(self):
pass
gen_ext.generate(Nanika)
こーいうのが、
typedef struct {
PyObject_HEAD
PyObject *y;
PyObject *x;
} Nanika;
static PyObject *
Nanika_new( PyTypeObject *type, PyObject *args, PyObject *kwds )
{
Nanika *self;
self = (Nanika *)type->tp_alloc(type, 0);
return (PyObject *)self;
}
static int
Nanika_init( Nanika *self, PyObject *args )
{
return 0;
}
static void
Nanika_dealloc( Nanika *self )
{
}
static PyObject *
Nanika_nanika_method( Nanika *self, PyObject *args )
{
}
static PyMethodDef Nanika_methods[] = {
{"nanika_method", (PyCFunction)Nanika_nanika_method, METH_VARARGS, ""},
{NULL}
};
static PyMemberDef Nanika_members[] = {
{"y", T_OBJECT_EX, offsetof(Nanika, y), 0, ""},
{"x", T_OBJECT_EX, offsetof(Nanika, x), 0, ""},
{NULL}
};
PyTypeObject NanikaType = {
PyObject_HEAD_INIT(0)
0, /*ob_size*/
"Nanika", /*tp_name*/
sizeof(Nanika),
0, /*tp_itemsize*/
(destructor)Nanika_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"", /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
Nanika_methods,
Nanika_members,
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
(initproc)Nanika_init,
0, /* tp_alloc */
Nanika_new
};
こーなる
wo