Obtener clase que define el método

¿Cómo puedo obtener la clase que definió un método en Python?

Me gustaría que el siguiente ejemplo imprima ” __main__.FooClass “:

 class FooClass: def foo_method(self): print "foo" class BarClass(FooClass): pass bar = BarClass() print get_class_that_defined_method(bar.foo_method) 

 import inspect def get_class_that_defined_method(meth): for cls in inspect.getmro(meth.im_class): if meth.__name__ in cls.__dict__: return cls return None 

Gracias Sr2222 por señalar que me estaba perdiendo el punto …

Aquí está el enfoque corregido que es como el de Alex pero que no requiere importar nada. Sin embargo, no creo que sea una mejora, a menos que haya una gran jerarquía de clases heredadas, ya que este enfoque se detiene tan pronto como se encuentra la clase definitoria, en lugar de devolver toda la herencia como getmro hace getmro . Como se dijo, este es un escenario muy poco probable.

 def get_class_that_defined_method(method): method_name = method.__name__ if method.__self__: classes = [method.__self__.__class__] else: #unbound method classes = [method.im_class] while classes: c = classes.pop() if method_name in c.__dict__: return c else: classes = list(c.__bases__) + classes return None 

Y el ejemplo:

 >>> class A(object): ... def test(self): pass >>> class B(A): pass >>> class C(B): pass >>> class D(A): ... def test(self): print 1 >>> class E(D,C): pass >>> get_class_that_defined_method(A().test)  >>> get_class_that_defined_method(A.test)  >>> get_class_that_defined_method(B.test)  >>> get_class_that_defined_method(C.test)  >>> get_class_that_defined_method(D.test)  >>> get_class_that_defined_method(E().test)  >>> get_class_that_defined_method(E.test)  >>> E().test() 1 

La solución de Alex devuelve los mismos resultados. Mientras se pueda usar el enfoque de Alex, lo usaría en lugar de este.

No sé por qué nadie lo ha mencionado o por qué la respuesta principal tiene 50 votos positivos cuando es tan lento como el infierno, pero también puede hacer lo siguiente:

 def get_class_that_defined_method(meth): return meth.im_class.__name__ 

Para Python 3, creo que esto cambió y tendrás que buscar en .__qualname__ .

Comencé a hacer algo similar, básicamente la idea era verificar cada vez que un método en una clase base se había implementado o no en una subclase. Resultó que la forma en que lo hice originalmente no pude detectar cuando una clase intermedia estaba implementando el método.

Mi solución para esto era bastante simple en realidad; estableciendo un atributo de método y probando su presencia más tarde. Aquí hay una simplificación de todo esto:

 class A(): def method(self): pass method._orig = None # This attribute will be gone once the method is implemented def run_method(self, *args, **kwargs): if hasattr(self.method, '_orig'): raise Exception('method not implemented') self.method(*args, **kwargs) class B(A): pass class C(B): def method(self): pass class D(C): pass B().run_method() # ==> Raises Exception: method not implemented C().run_method() # OK D().run_method() # OK 

ACTUALIZACIÓN: En realidad, llame al method() desde run_method() (¿no es ese el espíritu?) Y run_method() que pase todos los argumentos sin modificar al método.

PD: Esta respuesta no responde directamente a la pregunta. En mi humilde opinión hay dos razones por las que uno querría saber qué clase definió un método; La primera es señalar con el dedo a una clase en el código de depuración (como en el manejo de excepciones), y la segunda es determinar si el método se ha vuelto a implementar (donde el método es un código auxiliar que debe ser implementado por el progtwigdor). Esta respuesta resuelve ese segundo caso de una manera diferente.