Obter funções substituídas da subclasse

19

Existe uma maneira de obter todas as funções substituídas de uma subclasse em Python?

Exemplo:

class A:
    def a1(self):
        pass

    def a2(self):
        pass


class B(A):
    def a2(self):
        pass

    def b1(self):
        pass

Aqui, eu gostaria de obter uma lista ["a2"]para um objeto de classe B(ou para o próprio objeto de classe), pois a classe Bsubstitui apenas um único método, a saber a2.

Andreas Schörgenhumer
fonte

Respostas:

18

Você pode acessar as classes principais com cls.__bases__, encontrar todos os atributos dos principais dire acessar todos os atributos da própria classe com vars:

def get_overridden_methods(cls):
    # collect all attributes inherited from parent classes
    parent_attrs = set()
    for base in cls.__bases__:
        parent_attrs.update(dir(base))

    # find all methods implemented in the class itself
    methods = {name for name, thing in vars(cls).items() if callable(thing)}

    # return the intersection of both
    return parent_attrs.intersection(methods)
>>> get_overridden_methods(B)
{'a2'}
Aran-Fey
fonte
varsera a coisa que eu estava perdendo. muito obrigado pela (incrivelmente) resposta rápida!
Andreas Schörgenhumer 24/10/19
parent_attrsem uma linha, se você quiser:parent_attrs = {a for b in cls.__bases__ for a in dir(b)}
wjandrea
3

Você pode fazer uso da __mro__tupla, que contém a ordem de resolução do método.

Para o seu exemplo:

>>> B.__mro__
( <class '__main__.B'>, <class '__main__.A'>, <class 'object'>) 

Assim, você pode percorrer essa tupla e verificar se um Bmétodo também está em uma das outras classes.

Adelin
fonte
Isso não excluirá o método predefinido, como qualquer método dunder ,__init__, __eq__, ....... etc
Charif DZ
0
class A:

    def a1(self):
        pass

    def a2(self):
        pass


class B(A):

    def a2(self):
        super().a2()  
        pass

    def b1(self):
        pass
obj = B()

obj.a2()   # ***first give the output of parent class then child class***
Manish Sharma
fonte
11
Eu acho que você não entendeu a pergunta. Classes Ae Bnão podem ser modificadas. O OP quer saber qual dos Bmétodos substitui um dos Amétodos.
Wjandrea