Class extension confusion :(

r0g aioe.org at technicalbloke.com
Wed Nov 10 23:22:38 EST 2010


On 10/11/10 09:52, Peter Otten wrote:
> r0g wrote:
>
>> I have a subclass of BaseHHTPRequestHandler which uses a dictonary
>> "paths" and a function "api_call" which are defined in the main
>> namespace of the module. I'd rather I was able to pass these object to
>> the constructor and store them as data attributes "self.paths" and
>> "self.api_call" but I'm not sure how to do that properly. My
>> understanding is that one may extend a constructor by defining it's
>> __init__ method, calling the parents constructor and then adding ones
>> own attributes to taste. What I don't understand is where or how I am
>> supposed to get these extra constructor arguments into the class given
>> that I don't instantiate it myself, it is seemingly instantiated by
>> HTTPServer class that I pass it to e.g.
>>
>> httpd = HTTPServer(server_address, PlainAJAXRequestHandler)
>>
>> I wondered if I ought to instantiate an instance of
>> PlainAJAXRequestHandler, set the attributes (either manually or by
>> extending it's constructor) and pass that to HTTPServer but I figured it
>> expects a class not an instance as it probably wants to spawn one
>> instance for each request so that would be a non starter. Might I need
>> to subclass HTTPServer, find the bit that instantiates the request
>> handler and override that so it passes it's constructor more parameters?
>> Right now I'm pretty confused, can somebody please tell me how I might
>> accomplish this, what I'm failing to grasp or point me to the docs that
>> explain it - I've spent the last hour or two plowing through docs to no
>> avail, I guess it's a case of keyword ignorance on my part! Code
>> follows...
>
> Try passing a factory function instead of a class. Untested:
>
> from functools import partial
>
> class PlainAJAXRequestHandler(BaseHTTPRequestHandler):
>      def __init__(self, api_call, paths, *args, **kw):
>          BaseHTTPRequestHandler.__init__(self, *args, **kw)
>          self.api_call = api_call
>          self.paths = paths
>
> paths = ...
> api_call = ...
>
> httpd = HTTPServer(
>      server_address,
>      partial(PlainAJAXRequestHandler, paths, api_call))
>


Great, that looks ideal Peter, thanks very much :)

One more question quick question if you have time... I actually subclass 
the class in question later on to provide an SSL secured connection, is 
it possible (or even advisable) to do the following to spare me having 
to modify the derived classes init (and any subsequent classes' inits) 
too?...

PlainAJAXRequestHandler = partial(PlainAJAXRequestHandler, paths, api_call))

^??? Remap name to new extended class

class SecureAJAXRequestHandler(PlainAJAXRequestHandler):
     def setup(self):
         self.connection = self.request
         self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
         self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)

^??? therefore no init needed?


Cheers,

Roger




More information about the Python-list mailing list