Не наследовать некоторые (выбранные) методы от производных классов

Скажем, например, у меня есть два (python (3.3)) класса a и b со своими собственными методами:

class a:
    def m1(self):
        print("Hi 1")
    def m2(self):
        print("Hi 2")
        ##...other methods...
class b(a):
    def k1(self):
        print("Other hi")

Как мне сделать так, чтобы класс b наследует все методы от a кроме (например) m2? (кроме копирования / вставки, это не считается.) Так что выражение a.m2() было бы законно, но b.m2() бросил бы AttributeError,

4 ответа

Решение

Вы можете получить желаемый эффект, сделав братьев и сестер "a" и "b", а не родителем и ребенком. Это может работать для вас:

class p:
    def m1(self):
        print("Hi 1")

class a(p):
    def m2(self):
        print("Hi 2")

class b(a):
    def k1(self):
        print("Other hi")

Таким образом, все эти методы теперь действительны, остальные выдают AttributeErrors:

a.m1()
a.m2()
b.m1()
b.k1()

Почему вы хотите это сделать? Весь смысл наследования классов в том, чтобы иметь возможность проверить, что экземпляры b также случаи a; isinstance(b(), a) является True по причине. Удаляя методы из b ты плохо разбиваешь эту модель.

Вместо сделать a есть меньше методов, и добавить c иметь те, которые b не нужно:

class a:
    def m1(self):
        print("Hi 1")
        ##...other methods...

class b(a):
    def k1(self):
        print("Other hi")

class c(a):
    def m2(self):
        print("Hi 2")

Или вы не могли наследовать отa и просто скопировать методы из a по мере необходимости:

class b:
    # copied methods
    m1 = a.m1

    def k1(self):
        print("Other hi")

Сейчас b это a больше не верно, ожидание того, что все aМетоды реализованы больше не будет.

Если a полностью находится вне вашего контроля и существует слишком много методов для копирования, возможно, используйте прокси с __getattr__ и проходя через все, кроме m2, Последний метод канавы может быть реализовать m2 и поднять AttributeError, но это должно быть только последним средством.

Это на самом деле не имеет смысла. Точка наследования заключается в том, что наследующий объект точно совместим с базовым типом. Это принцип подстановки Лискова: везде, где приемлем объект исходного типа, также будет объект производного типа.

Если вы измените свой производный тип так, чтобы не было некоторых членов базового типа, то вы нарушаете этот принцип. С динамической типизацией в Python это не будет такой большой проблемой, но она все еще нарушает идею, лежащую в основе.

Так что ты действительно не должен этого делать.

Если b наследуется от a, он должен наследовать каждый метод. Это наследство. Но если это необходимо (обратите внимание, что это не рекомендуется), вы можете переопределить m2() метод, поэтому он поднимает Exception когда звонили.

class b(a):
    def m2(self):
        raise Exception("...")
Другие вопросы по тегам