How to instantiate a different class in a constructor?

Diez B. Roggisch deets at nospam.web.de
Tue Jan 23 06:23:26 EST 2007


> I have a class URI and a bunch of derived sub-classes for example
> HttpURI, FtpURI, HttpsURI, etc. (this is an example, I know there is
> module urllib & friends, however my actual problem however maps very
> well to this example).
> 
> Now I want to pass a string to constructor of URI() and get an instance
> of one of the subclasses back. For example uri=URI('http://abcd/...')
> will make 'uri' an instance of HttpURI class, not instance of URI.
> 
> To achieve this I have a list of all subclasses of URI and try to
> instantiate one by one in URI.__new__(). In the case I pass e.g. FTP URI
> to HttpURI constructor it raises ValueError exception and I want to test
> HttpsURI, FtpURI, etc.

<snip/>


Use a factory function:

class UriBase(object):
    REGISTRY = {}

class HttpUri(UriBase):
    pass

UriBase.REGISTRY['http'] = HttpUri

def URI(arg):
    return UriBase.REGISTRY[get_protocol(arg)](arg)

This is untested and could be enhanced by e.g. using metaclasses to perform
the registration automagicall, but I think you get the idea.

Diez



More information about the Python-list mailing list