我使用PyCLIPS将剪辑集成到Python中。Python方法使用clips.RegisterPythonFunction(method, optional-name)在剪辑中注册。由于我必须注册几个函数,并且希望保持代码清晰,所以我正在寻找一个装饰器来进行注册。
现在是这样做的:
class CLIPS(object):
...
def __init__(self, data):
self.data = data
clips.RegisterPythonFunction(self.pyprint, "pyprint")
def pyprint(self, value):
print self.data, "".join(map(str, value))这是我想要做的:
class CLIPS(object):
...
def __init__(self, data):
self.data = data
#clips.RegisterPythonFunction(self.pyprint, "pyprint")
@clips_callable
def pyprint(self, value):
print self.data, "".join(map(str, value))它保留了方法的编码并将它们注册在一个地方。
注意:我在多处理器设置中使用它,其中CLIPS进程在一个单独的进程中运行,如下所示:
import clips
import multiprocessing
class CLIPS(object):
def __init__(self, data):
self.environment = clips.Environment()
self.data = data
clips.RegisterPythonFunction(self.pyprint, "pyprint")
self.environment.Load("test.clp")
def Run(self, cycles=None):
self.environment.Reset()
self.environment.Run()
def pyprint(self, value):
print self.data, "".join(map(str, value))
class CLIPSProcess(multiprocessing.Process):
def run(self):
p = multiprocessing.current_process()
self.c = CLIPS("%s %s" % (p.name, p.pid))
self.c.Run()
if __name__ == "__main__":
p = multiprocessing.current_process()
c = CLIPS("%s %s" % (p.name, p.pid))
c.Run()
# Now run CLIPS from another process
cp = CLIPSProcess()
cp.start()发布于 2012-05-17 17:48:30
现在,通过使用装饰器在要在中注册的方法上设置属性,并在init中使用inspect来获取并注册方法,从而使其正常工作。也可以使用一些命名策略,但我更喜欢使用装饰器来使注册更加明确。可以在初始化剪辑环境之前注册Python函数。这就是我所做的。
import inspect
def clips_callable(func):
from functools import wraps
@wraps(func)
def wrapper(*__args,**__kw):
return func(*__args,**__kw)
setattr(wrapper, "clips_callable", True)
return wrapper
class CLIPS(object):
def __init__(self, data):
members = inspect.getmembers(self, inspect.ismethod)
for name, method in members:
try:
if method.clips_callable:
clips.RegisterPythonFunction(method, name)
except:
pass
...
@clips_callable
def pyprint(self, value):
print self.data, "".join(map(str, value))为了完整起见,下面包含了test.clp中的剪辑代码。
(defrule MAIN::start-me-up
=>
(python-call pyprint "Hello world")
)如果有人知道更优雅的方法,请让我知道。
发布于 2012-05-16 20:57:19
这样做应该是相当简单的:
# mock clips for testing
class clips:
@staticmethod
def RegisterPythonFunction(func, name):
print "register: ", func, name
def clips_callable(fnc):
clips.RegisterPythonFunction(fnc, fnc.__name__)
return fnc
@clips_callable
def test(self):
print "test"
test()edit:如果在类方法上使用它,它将只注册未绑定的方法。因此,如果在没有类实例作为第一个参数的情况下调用函数,它将不起作用。因此,这可用于注册模块级函数,但不能用于注册类方法。为此,您必须在__init__中注册它们。
发布于 2012-05-17 12:43:14
mata提出的优雅的解决方案似乎行不通,因为CLIPS环境应该在向其注册方法之前进行初始化。
我不是Python专家,但从一些搜索来看,inspect.getmembers()和hasattr()的组合似乎可以为您做这件事-您可以循环您的类的所有成员,并将具有@clips_callable属性的成员注册到剪辑。
https://stackoverflow.com/questions/10618805
复制相似问题