I have an interface class called iResource, and a number of subclasses, each of which implement the “request” method. The request functions use socket I/O to other machines, so it makes sense to run them asynchronously, so those other machines can work in parallel.
The problem is that when I start a thread with iResource.request and give it a subclass as the first argument, it’ll call the superclass method. If I try to start it with “type(a).request” and “a” as the first argument, I get “” for the value of type(a). Any ideas what that means and how to get the true type of the method? Can I formally declare an abstract method in Python somehow?
EDIT: Including code.
def getSocialResults(self, query=''):
#for a in self.types["social"]: print type(a)
tasks = [type(a).request for a in self.types["social"]]
argss = [(a, query, 0) for a in self.types["social"]]
grabbers = executeChainResults(tasks, argss)
return igrabber.cycleGrabber(grabbers)
“executeChainResults” takes a list “tasks” of callables and a list “argss” of args-tuples, and assumes each returns a list. It then executes each in a separate thread, and concatenates the lists of results. I can post that code if necessary, but I haven’t had any problems with it so I’ll leave it out for now.
The objects “a” are DEFINITELY not of type iResource, since it has a single constructor that just throws an exception. However, replacing “type(a).request” with “iResource.request” invokes the base class method. Furthermore, calling “self.types[“social”][0].request” directly works fine, but the above code gives me: “type object ‘instance’ has no attribute ‘request'”.
Uncommenting the commented line prints <type 'instance'> several times.
You can just use the bound method object itself:
If you insist on calling your methods through the base class you could also do it like this:
Result:
Python doesn’t support interfaces as e.g. Java does. But with the
abcmodule you can ensure that certain methods must be implemented in subclasses. Normally you would do this with theabc.abstractmethod()decorator, but you still could not call the subclasses method through the base class, like you intend. I had a similar question once and I had the idea of thevirtualmethod()decorator. It’s quite simple. It essentially does the same thing asabc.abstratmethod(), but also redirects the call to the subclasses method. The specifics of theabcmodule can be found in the docs and in PEP3119.BTW: I assume you’re using Python >= 2.6.