大家好
我正在尝试使用Python(2.7.6)创建一个“插件”系统。我有一个类,它在自定义硬件板上实现基本操作(使用C++共享库),我希望开发人员能够使用某种插件系统来扩展这个类的功能。由于各种原因,所有功能都应该在同一级别上可用(例如,一个类实例),所以所有的函数调用,无论是显式实现还是从插件导入,都应该可以从board实例调用。在
此外,这些插件中的函数需要使用调用类中定义的函数。例如,一个通道化插件需要使用在导入它的Board类中实现的读写调用。我从插件的抽象基类开始,如下所示:class FirmwareBlock(object):
""" Abstract super class which must be used to implement firmware
block plugins to be used with the access layer """
def __init__(self):
""" Class initialiser """
# Define class as an abstract class
__metaclass__ = ABCMeta
@abstractmethod
def initialise(self):
""" Abstract method where all firmware block initialisation should be performed """
pass
@abstractmethod
def status_check(self):
""" Abstract method where all status checks should be performed """
pass
@abstractmethod
def clean_up(self):
""" Abstract method where all cleaning up should be performed when unloading firmware """
pass
此类中定义的函数必须由所有子类实现。反过来,子类可以实现它们自己的特定函数,这些函数必须包含在board类中,例如:
^{pr2}$
然后,board(calling)类应该能够加载模块,检查自定义函数并包装它们,以便可以直接从中调用它们。这就是我现在所拥有的:def loadPlugin(self, plugin):
# Check if module is available
if plugin not in self._availablePlugins:
print "Module %s is not available" % plugin
return Error.Failure
# Get list of class methods and remove those availale in superclass
methods = [name for name, mtype in
inspect.getmembers(eval(plugin), predicate=inspect.ismethod)
if name not in
[a for a, b in inspect.getmembers(FirmwareBlock, predicate=inspect.ismethod)] ]
# Create plugin instances
instance = globals()[plugin]
self.__dict__[plugin] = instance
# Import plugins function into this class
for method in methods:
# Link class method to function pointer
self.__dict__[method] = getattr(instance, method)
这应该允许我调用插件方法,但是插件不能访问板本身定义的函数。当然,当实例化类时,我可以将board的实例传递给init,但是这将插件与board类紧密地耦合在一起。我想知道是否有更好的方法来实现这一点(例如,提取方法并将其直接附加到board类,假设没有使用实例成员)