2

How can I get the class that defined a method in Python?

For example

class A(object):
    def meth(self):
        return **get_current_class()**
class B(A):
    def meth(self):
        do_something
        return super(B,self).meth()

>>> b=B()
>>> b.meth() ##that return the class A

Since b.__class__ is always the actual class of b(that is B),and what I want is the class which actual defined the method(that should be A),so self.__class__ is useless.

yjmade
  • 441
  • 4
  • 9
  • possible duplicate of [Get class that defined method](http://stackoverflow.com/questions/961048/get-class-that-defined-method) – tobych Apr 01 '14 at 07:37

2 Answers2

1

To return the class that defined the method, the simplest way would be to just do it directly:

class A(object):
    def meth(self):
        return A

If meth is defined outside the class -- and presumably attached to more than one class -- it may not be feasible to hardcode the class in the body of meth. In that case, perhaps the easiest (only?) way for meth to know the class on which it is defined is to store that information in meth (as an attribute) at the time it is attached to the class.

Instead of attaching the function meth to the class A with

A.meth = meth

I propose using a function setmeth which performs both A.meth = meth and meth.thisclass = A:

def setmeth(cls, name, meth):
    setattr(cls, name, meth)
    setattr(meth, 'thisclass', cls)

def meth(self):
    print(meth.thisclass)

class A(object): pass
setmeth(A, 'meth', meth)

class B(A):
    def meth(self):
        return super(B, self).meth()

b=B()
b.meth() ##that return the class A

prints

<class '__main__.A'>
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • in my case,I can't simply type this class name because I'm implementing a function which need to use the class of the method who invoke it and I don't want to put this class in the argument everytime. – yjmade Sep 27 '13 at 02:48
  • I'm sorry; I don't quite follow you. Do you mean the function is defined outside of the class? Could you post some more code to make the situation clearer? – unutbu Sep 27 '13 at 02:52
  • @ubuntu yes,this function (get_current_class) is defined outside an it could return A inside A.meth. – yjmade Sep 27 '13 at 02:59
  • 1
    http://www.python.org/dev/peps/pep-3130/ ,in the pep 3130 ,\__class__ is exactly what I want,Unfortunately it has been rejected – yjmade Sep 27 '13 at 03:01
0

This is a bit of an odd thing to want to do, and you can't do it without getting extremely hacky. One possible solution is to realize that a method is a member of __dict__ on the class that defines it, so you can ascend the MRO to find the first one that has the method name in that dict:

def get_class_for_method(self, method_name):
    for cls in self.__class__.mro():
        if method_name in cls.__dict__:
            return cls
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • In yjmade's case, `self.__class__.mro()` includes `B` before `A`, so `B.meth` will be found before `A.meth`. Unfortunately, I don't think this is going to work... – unutbu Sep 26 '13 at 13:17
  • yes,@ubuntu is right,I need to know which class's method invoke the get_current_class function – yjmade Sep 27 '13 at 02:51