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.
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...
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:
...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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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)
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.