python - Obter funções substituídas da subclasse




reflection overriding (3)

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 da classe B (ou para o próprio objeto de classe), já que a classe B substitui apenas um único método, a2 .


Apenas para elaborar mais, quando você define qualquer atributo, é adicionado ao atributo __dict__ da Class :

class A:
    def a1(self):
        pass 

print('a1' in A.__dict__) # True Note: vars(A) == A.__dict__  

e para verificar se um atributo é um método, use callable built-in que retorne True se o objeto for callable (função, método, classe, ... etc):

 print(callable(A.__dict__['a1']))  # True

E agora, mesmo que B seja subclasse de A mas não tenha definido a1 esse atributo não será adicionado a B.__dict__ :

   class B(A):
      pass

   print('a1' in B.__dict__)  # False 

Portanto, apenas comparando os valores dos atributos __dict__ você obterá o método de substituição, que é o método que existe em A.__dict__ e B.__dict__

  override_method = [attr for attr in B.__dict__ if attr in A.__dict__ and callable(A.__dict__[attr])]

Nota: Eu poderia substituir A.__dict__ por vars(A) para simplificar o Código, mas eu queria mostrar esse atributo especial que é adicionado pelo python para o novo desenvolvedor do Python.


Você pode acessar as classes pai com cls.__bases__ , encontrar todos os atributos dos pais com dir e 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'}

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***






subclass