inherit an instance, or something
I have what might seem to be a strange situation. I have a plugin-system which loads plugins from DSO's. Each plugin presents a factory function which returns an object that implements an abstract interface (a class). The interface could look something like this: class plugin { virtual void set_parameter (const char *name, int value); ... }; The plugin class is easily wrapped using Boost.Python, and a generic factory function could be exported which loads a DSO, finds the factory function, invokes it and returns the created instance; plugin *make_plugin (const char *dso_name); The problem comes when I in python wants to inherit from a specific plugin. The simplest way is probably to do something like this; (case 1) class my_extended_plugin(plugin): def __init__(self, ...): plugin.__init__(self) self.o = make_plugin('libmy-plugin.so') self.set_parameter = self.o.set_parameter But that to me is not a clean solution. It makes it hard to inherit From my_extended_plugin. (not possible to invoke my_extended_plugin.set_parameter correctly.) What I really want is something like this; (case 2, dso_plugin inherits plugin) class my_extended_plugin(dso_plugin): def __init__(self, ...): dso_plugin.__init__(self, 'libmy-plygin.so') Where dso_plugin.__init__ would "replace" the held pointer for 'self' with the one that make_plugin('libmy-plugin.so') returns. Is it possible to do this in anyway, or must I reside to case 1? ~j
On 11/8/06, Johan Rydberg <jrydberg@gnu.org> wrote:
I have what might seem to be a strange situation. I have a plugin-system which loads plugins from DSO's. Each plugin presents a factory function which returns an object that implements an abstract interface (a class). The interface could look something like this:
class plugin { virtual void set_parameter (const char *name, int value); ... };
The plugin class is easily wrapped using Boost.Python, and a generic factory function could be exported which loads a DSO, finds the factory function, invokes it and returns the created instance;
plugin *make_plugin (const char *dso_name);
The problem comes when I in python wants to inherit from a specific plugin. The simplest way is probably to do something like this;
(case 1)
class my_extended_plugin(plugin): def __init__(self, ...): plugin.__init__(self) self.o = make_plugin('libmy-plugin.so') self.set_parameter = self.o.set_parameter
But that to me is not a clean solution. It makes it hard to inherit From my_extended_plugin. (not possible to invoke my_extended_plugin.set_parameter correctly.)
What I really want is something like this;
(case 2, dso_plugin inherits plugin)
class my_extended_plugin(dso_plugin): def __init__(self, ...): dso_plugin.__init__(self, 'libmy-plygin.so')
Where dso_plugin.__init__ would "replace" the held pointer for 'self' with the one that make_plugin('libmy-plugin.so') returns.
Is it possible to do this in anyway, or must I reside to case 1?
I think you can take another approach - mix between first one and the second + automatic redirection: class dso_plugin(plugin): def __init__(self, ...): plugin.__init__(self) self.__o = make_plugin('libmy-plugin.so') def __getattr__( self, name ): return getattr( self.__o, name ) Now you can derive your plug-ins from the dso_plugin. P.S. I am not sure about exact __getattr__ implementation. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/
"Roman Yakovenko" <roman.yakovenko@gmail.com> writes:
Thanks Roman!
>> class my_extended_plugin(dso_plugin):
>> def __init__(self, ...):
>> dso_plugin.__init__(self, 'libmy-plygin.so')
>>
>> Where dso_plugin.__init__ would "replace" the held pointer for 'self'
>> with the one that make_plugin('libmy-plugin.so') returns.
>> [...]
> I think you can take another approach - mix between first one and the second
> + automatic redirection:
>
> class dso_plugin(plugin):
> def __init__(self, ...):
> plugin.__init__(self)
> self.__o = make_plugin('libmy-plugin.so')
>
> def __getattr__( self, name ):
> return getattr( self.__o, name )
>
> Now you can derive your plug-ins from the dso_plugin.
>
> P.S.
> I am not sure about exact __getattr__ implementation.
But __getattr__ will only be invoked for fetching attributes from an
instance of dso_plugin, right? Will I be able to do things like
dso_plugin.set_parameter(self, ...). In other words, override a method
and invoke the default implementation.
~j
On 11/8/06, Johan Rydberg <jrydberg@gnu.org> wrote:
> "Roman Yakovenko" <roman.yakovenko@gmail.com> writes:
>
> Thanks Roman!
>
> >> class my_extended_plugin(dso_plugin):
> >> def __init__(self, ...):
> >> dso_plugin.__init__(self, 'libmy-plygin.so')
> >>
> >> Where dso_plugin.__init__ would "replace" the held pointer for 'self'
> >> with the one that make_plugin('libmy-plugin.so') returns.
> >> [...]
> > I think you can take another approach - mix between first one and the second
> > + automatic redirection:
> >
> > class dso_plugin(plugin):
> > def __init__(self, ...):
> > plugin.__init__(self)
> > self.__o = make_plugin('libmy-plugin.so')
> >
> > def __getattr__( self, name ):
> > return getattr( self.__o, name )
> >
> > Now you can derive your plug-ins from the dso_plugin.
> >
> > P.S.
> > I am not sure about exact __getattr__ implementation.
>
> But __getattr__ will only be invoked for fetching attributes from an
> instance of dso_plugin, right? Will I be able to do things like
> dso_plugin.set_parameter(self, ...). In other words, override a method
> and invoke the default implementation.
Take a look on next link:
http://66.102.9.104/search?q=cache:lwJDtRkG76IJ:aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295+%22Automatic+delegation+as+an+alternative+to+inheritance%22&hl=en&ct=clnk&cd=1
--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
participants (2)
-
Johan Rydberg -
Roman Yakovenko