[python-nl] Problem passing instance (self) when calling CLIPS

Frans Schneider f.schneider at de-bleek.demon.nl
Fri Dec 25 16:35:56 CET 2009


Op vrijdag 25-12-2009 om 14:46 uur [tijdzone +0100], schreef Dirkjan
Ochtman:
> On Fri, Dec 25, 2009 at 12:33, Schneider <f.schneider at de-bleek.demon.nl> wrote:
> > import clips
> >
> > class Callable(object):
> >     def __init__(self, func):
> >         self._func = func
> >         clips.RegisterPythonFunction(func)
> >         r = clips.BuildRule("%s-rule" % func.__name__,
> >                             "?f <- (duck)",
> >                             ""(retract ?f)
> >                             (python-call %s \"arg2py\")""" % func.__name__,
> >                             "The %s rule" % func.__name__)
> >         print r.PPForm()
> >         print "%s being initialized" % self._func.__name__
> >
> >     def __call__(self, *args, **kwargs):
> >         print "I am never executed"
> >         return self._func(*args, **kwargs)
> >
> > class MyObject(object):
> >
> >     @Callable
> >     def MyMethod(self):
> >         print "I am being called by CLIPS with the arg", self
> >
> >     def Assert(self):
> >         self.data = "DATA"
> >         clips.Assert("(duck)")
> >
> > if __name__ == "__main__":
> >     clips.Reset()
> >     myObject = MyObject()
> >     myObject.Assert()
> >     clips.Run(100)
> >     print "Bye"
> >
> > The output looks like:
> >
> > (defrule MAIN::MyMethod-rule "The MyMethod rule"
> >    ?f <- (duck)
> >    =>
> >    (retract ?f)
> >    (python-call MyMethod "arg2py"))
> >
> > MyMethod being initialized
> > I am being called by CLIPS with the arg arg2py
> > Bye
> >
> > Please note that the __call__ method in the decorator is not being called
> > from CLIPS.
> 
> That's because you aren't calling any MyMethod here?
> 
No, asserting the fact and giving the CLIPS engine the run instructrion
will fire the rule which does the python-call to MyMethod. As you see
from the output, this works since the output shows 'MyMethod being
initialized'

> > I don’t understand the internals but assume that calling a Python function
> > from a C program will not invoke __call__.
> 
> I think "calling", which you can override in pure Python by defining a
> __call__ method, uses a call hook on the C-registered type. IOW, just
> attaching a method called __call__ to your C-defined class probably
> won't work, you need to attach it to the call hook on the C-level
> struct.
> 
I am calling the python class method MyMethod from CLIPS, which is C.
When I call MyMethod from python, the __call__ in the decorator is
executed. Not in this case. I am not very familiair with decorators, so
there probably is a very good reason for this behaviour.

> Hope that helps (I haven't actually worked much with the C API myself),
> 
> Dirkjan

More important than the __call__ issue, is the issue about encoding
something in Python that refers to the instance self, in a type that
CLIPS (C) can accept and return that in the python-call so I can use the
instance again.
> _______________________________________________
> Python-nl mailing list
> Python-nl at python.org
> http://mail.python.org/mailman/listinfo/python-nl
> 



More information about the Python-nl mailing list