Try something like:
class BaseRequest:
name = None
class FooRequest(BaseRequest):
name = 'I-95'
def response(self):
return "foo"
class BarRequest(BaseRequest):
name = 'P-22'
def response(self):
return "bar"
class RequestManager:
def __init__(self):
self.requests = {
FooRequest.name: FooRequest,
BarRequest.name: BarRequest
}
def generate_request(self, name):
if name in self.requests:
return self.requests[name]()
def register_request(self, request_class):
assert issubclass(request_class, BaseRequest), \
'Request class not a subclass of BaseRequest'
assert hasattr('name', request_class) and isinstance(request_class.name, str), \
'Request name not correctly configured'
self.requests[request_class.name] = request_class
And then:
manager = RequestManager()
request = manager.generate_request('I-95')
if request is not None:
print(request.response()) # "foo"
And for registering new requests:
class NewRequest(BaseRequest):
name = 'N-1'
def response(self):
return "new"
manager = RequestManager()
manager.register_request(NewRequest)
request = manager.generate_request('N-1')
if request is not None:
print(request.response()) # "new"
I personally think this is better done using a Singleton-pattern for the RequestManager (untested!):
class RequestManager:
instance = None
class __RequestManager:
requests = {
FooRequest.name: FooRequest,
BarRequest.name: BarRequest
}
def generate_request(self, name):
if name in self.requests:
return self.requests[name]()
def register_request(self, request_class):
assert issubclass(request_class, BaseRequest), \
'Request class not a subclass of BaseRequest'
assert hasattr('name', request_class) and isinstance(request_class.name, str), \
'Request name not correctly configured'
self.requests[request_class.name] = request_class
def __new__(cls):
if not cls.instance:
cls.instance = cls.__RequestManager()
return cls.instance
@staticmethod
def getInstance():
return RequestManager()
This creates a statically accessible RequestManager instance:
manager = RequestManager.getInstance()
# Rest same as before, register some requests, etc.
manager2 = RequestManager.getInstance() # This is actually the same manager ie. the same instance!
manager
and manager2
share the same requests dictionary, so updates via one of them applies to both (technically speaking to the same manager, because you retrieve the same instance twice)