Pedram Amini has got a pretty neat post up on reverse engineering the protocol for a USB device. If you haven’t seen it yet (it was linked from Slashdot) it’s worth reading. However, he includes some Python code which features a puzzling (to me, anyway) idiom, which took me a while to figure out.
How Does This Work?
Pedram’s code includes the following snippets:
class web_interface_handler (BaseHTTPServer.BaseHTTPRequestHandler): def __init__(self, request, client_address, server): BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server) self.missile = None
class web_interface_server (BaseHTTPServer.HTTPServer): def __init__(self, server_address, RequestHandlerClass, missile): BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass) self.RequestHandlerClass.missile = missile
self.server = web_interface_server(('', 12345), web_interface_handler, self.missile)
What’s puzzling is that
web_interface_server.__init__() sets a
missile member, while
web_interface_handler.__init__() sets an instance-level
missile member (to
None). Since the instance-level member will take precedence, how can a reference ever be made to the class-level
The relevant code is in the
def __init__(self, request, client_address, server): self.request = request self.client_address = client_address self.server = server try: self.setup() self.handle() self.finish() finally: sys.exc_traceback = None # Help garbage collection
This code is not overridden by the
BaseHTTPRequestHandler class (which inherits from it, and from which
web_interface_handler inherits). The significance of this code is that all the “work” done by a
BaseRequestHandler instance is done when it is initialized. Since this initialization code is invoked by
web_interface_server.__init__() before that function sets the instance-level
missile member, the code can make reference to the class-level member.
I would categorize this as “non-obvious”.