tags:

views:

226

answers:

2

Here is my guess, which doesn't work:

class BaseClass(object):
    def foo(self):
        return 'foo'
    def bar(self):
        return 'bar'
    def methods_implemented(self):
        """This doesn't work..."""
        overriden = []
        for method in ('foo', 'bar'):
            this_method = getattr(self, method)
            base_method = getattr(BaseClass, method)
            if this_method is not base_method:
                overriden.append(method)
        return overriden

class SubClass(BaseClass):
    def foo(self):
        return 'override foo'

o = SubClass()
o.methods_implemented()

Ideally, methods_implemented() would return ['foo'].

How?

(Why would I want to do this? My base class is an HTTP Resource class which has methods GET, POST etc. By default they return 405 Method Not Implemented. It also has a method OPTIONS which should return a 200 response with the header Allow set to the methods which any subclass implements.)

+3  A: 

Perhaps this?

>>> class BaseClass(object):
...     def foo(self):
...         return 'foo'
...     def bar(self):
...         return 'bar'
...     def methods_implemented(self):
...         """This does work."""
...         overriden = []
...         for method in ('foo', 'bar'):
...             this_method = getattr(self, method)
...             base_method = getattr(BaseClass, method)
...             if this_method.__func__ is not base_method.__func__:
...                 overriden.append(method)
...         return overriden
... 
>>> class SubClass(BaseClass):
...     def foo(self):
...         return 'override foo'
... 
>>> o = SubClass()
>>> o.methods_implemented()
['foo']

This checks whether the function objects behind the bound methods are the same.

Note, prior to Python 2.6, the __func__ attribute was named im_func.

Ned Deily
This works, with the exception that in my python-2.5 interpreter you need to check im_func, not __func__. Perhaps you could mention that in your answer. Thanks.
Tenac
You're welcome, though next time you might consider not marking questions like this as `community wiki`. Responders like to get their points!
Ned Deily
A: 

The methods, even though calling the same object, are NOT the same object. You must test to see if the functions wrapped in the unbound method are the same object.

I'm using 2.6 over here, so I also changed the class to inherit from object.

>>> class BaseClass(object):
...     def foo(self):
...         return 'foo'
...     def bar(self):
...         return 'bar'
...     def methods_implemented(self):
...         """This doesn't work..."""
...         overriden = []
...         for method in ('foo', 'bar'):
...             this_method = getattr(self, method).__func__
...             base_method = getattr(BaseClass, method).__func__
...             if this_method is base_method:
...                 overriden.append(method)
...         return overriden
... 
>>> class SubClass(BaseClass):
...     def foo(self):
...         return 'override foo'
... 
>>> o = SubClass()
>>> o.methods_implemented()
['bar']
Mike Boers