In a C++ library I have a class with private constructors and a factory:
class MyServer {
MyServer() {..};
public:
MyServer create(std::string &config);
};
With boost-python I create a wrapper which lets me use this factory:
from MyWrappedLibrary import MyServer, StartServer
server = MyServer.create('some: magic, config: string')
StartServer(server)
Now I want to add a method to MyServer like this:
from MyWrappedLibrary import MyServer, StartServer
class MyEnhancedServer(MyServer):
def __init__(self, config):
super().__init__(config)
def another_method(self):
do(something)
But of course this does not work since I can't instantiate MyServer
directly.
Of course I could create a class which doesn't derive from MyServer
but it would not feel good since I had to wrap every method:
class MyEnhancedServer:
def __init__(self, config):
self.core_instance = MyServer.create(config)
def foo_1(self): # wrapper
self.core_instance.foo_1()
def foo_2(self): # wrapper
return self.core_instance.foo_2()
def another_method(self):
do(something)
server = MyEnhancedServer('some: magic, config: string')
StartServer(server.core_instance)
Question: Is there a way to make the result of MyServer.create()
the 'base instance' of MyEnhancedServer?
The result would be something like this:
class MyEnhancedServer(MyServer):
def __init__(self, config):
self.MyServer = MyServer.create()
def another_method(self):
do(something)
A colleague told me how to do it but would not post an answer. The trick is to implement __new__()
and set the instance' class with this cool magic:
class MyEnhancedServer(MyServer):
def __new__(cls, config):
self = cls.create(config)
self.__class__ = cls.__class__(cls.__name__, (cls, ), {})
return self