Не наследовать некоторые (выбранные) методы от производных классов
Скажем, например, у меня есть два (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("...")