Menu

PyClips register callable

Help
2006-11-28
2013-04-25
  • Marco Nawijn

    Marco Nawijn - 2006-11-28

    Hello,

    I am a newbie to PyClips programming and are experimenting a bit with calling
    external python functions. Since the documentation speaks about 'callables' I
    assumed it would be possible to call Python objects that are instantiated from
    classes implementing the __call__ method. A little experiment teaches me that it
    does not. Am I doing something wrong or should the callable actually only be a
    function.

    Example:

    # This works
    def print_bar(*args):

         print 'Inside bar'
         print args

    clips.RegisterPythonFunction(print_bar)

    # This does not work

    class print_bar(object):

         def __call__(self, *args):
             print 'Inside bar'
             print args

    clips.RegisterPythonFunction(print_bar)

     
    • Francesco Garosi

      Hi Marco,

      actually the problem is in using the class definition (instead of an instance of the class which has a __call__ method) to register a Python function. PyCLIPS accepts whatever has an usable __call__ method, and when you define it in a class, it's actually implemented only on instances of that class. In fact, when you use the "call operator" (parentheses) on a class symbol, you normally do it in order to create a new instance...

      An example follows:

      >>> import clips
      >>> class print_bar(object):
          def __call__(self, *args):
              print "inside bar"
              print args

             
      >>> pb = print_bar()
      >>> clips.RegisterPythonFunction(print_bar, "print_bar")
      >>> clips.RegisterPythonFunction(pb, "pb")
      >>> clips.SendCommand('(python-call print_bar "arg")', True)

      Traceback (most recent call last):
        File "<pyshell#26>", line 1, in -toplevel-
          clips.SendCommand('(python-call print_bar "arg")', True)
        File ".../site-packages/clips/_clips_wrap.py", line 3268, in SendCommand
          _c.sendCommand(command, verbose)
      ClipsError: C09: unable to understand argument
      >>> print clips.ErrorStream.Read()

      [PYTHONXC1] Call to function print_bar failed.

      ...it just states that PyCLIPS could not actually perform a call to the print_bar object (which is a class definition, as said above). But on the other hand, with one of its instances - that can be used as a function - you'll see the following:

      >>> clips.SendCommand('(python-call pb "arg")', True)
      inside bar
      (<String 'arg'>,)
      >>> print clips.ErrorStream.Read()
      None

      ...and this is, I hope, what you were looking for. There is only a caveat for this: when you create the "pb" instance of print_bar, it has no __name__ attribute. So, in order to register it as a Python function in PyCLIPS, either you have to provide a name under which it is known to PyCLIPS as I did above, or you have to supply a __name__ member to pb (for example, via "pb.__name__ = "pb").

      I hope this will help.

      Cheers,

      F.

       

Log in to post a comment.