120 votes

Obtenir la classe cette méthode définie

Comment puis-je obtenir la classe qui a défini une méthode en Python?

Je voudrais que l'exemple suivant imprime " __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)
 

80voto

Alex Martelli Points 330805
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

8voto

estani Points 1167

Grâce Sr2222 de remarquer qu'il me manquait le point de...

Voici le corrigé de l'approche qui est juste comme Alex mais il n'a pas besoin d'importer quoi que ce soit. Je ne pense pas que c'est une amélioration, même si, à moins qu'il y a une énorme hiérarchie de classes héritées que cette approche s'arrête dès que la classe de définition est trouvé, au lieu de renvoyer l'ensemble de l'héritage, getmro n'. Comme l'a dit, c'est un très improbable.

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

Et l'Exemple:

>>> 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)
<class '__main__.A'>
>>> get_class_that_defined_method(A.test)
<class '__main__.A'>
>>> get_class_that_defined_method(B.test)
<class '__main__.A'>
>>> get_class_that_defined_method(C.test)
<class '__main__.A'>
>>> get_class_that_defined_method(D.test)
<class '__main__.D'>
>>> get_class_that_defined_method(E().test)
<class '__main__.D'>
>>> get_class_that_defined_method(E.test)
<class '__main__.D'>
>>> E().test()
1

Alex solution renvoie les mêmes résultats. Aussi longtemps que Alex approche peut être utilisée, je voudrais l'utiliser à la place de celui-ci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X