super, decorators and gettattribute

George Sakkis george.sakkis at gmail.com
Mon Jan 14 12:12:41 EST 2008


On Jan 12, 6:56 pm, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:

> On Sat, 12 Jan 2008 15:47:05 -0500, Mike Meyer wrote:
> > There's an apparently common bug here: you don't want to pass super
> > self.__class__, but the class that the method is bound to.
>
> Given an instance method, is it possible to easily determine what class
> it is defined in?
>
> I thought the im_class attribute might do it, but it apparently just
> points to self.__class__.
>
> >>> class Foo(object):
>
> ...     def foo(self):
> ...             pass
> ...>>> class Bar(Foo):
>
> ...     def bar(self):
> ...             pass
> ...>>> Bar().bar.im_class  # expecting Bar
>
> <class '__main__.Bar'>>>> Bar().foo.im_class  # hoping for Foo
>
> <class '__main__.Bar'>

Something like that seems to work for most cases:

from inspect import getmro

def getdef(obj,attr):
    try: objattrs = obj.__dict__
    except AttributeError:
        objattrs = obj.__slots__
    if attr in objattrs:
        return obj
    for cls in getmro(obj.__class__):
        if attr in cls.__dict__:
            return cls

>>> getdef(Bar(), 'bar')
<class '__main__.Bar'>

>>> getdef(Bar(), 'foo')
<class '__main__.Foo'>


It probably misses some edge cases but I can't think of any off the
top of my head.

George



More information about the Python-list mailing list