Это называется «monkeypatching», и в некоторых случаях вполне разумно.
Например, если вам нужно использовать чужой код (который вы не можете изменить), который зависит от SuperClass
, и вам нужно изменить поведение этого кода, ваш единственный реальный выбор - заменить методы на SuperClass
.
Однако, в вашем случае, по-видимому, нет веских оснований для этого. Вы определяете все подклассы SuperClass
, так почему бы просто не добавить еще один класс между ними?
class Intermediate(SuperClass):
def func3():
pass
class SubClass1(Intermediate):
def func1():
print 'hi'
Это не достаточно хорош для «функциональность, которая должна была в SuperClass
, но не было», если другой код, который вы не можете контролировать потребности, функциональность ... но когда это только код что нужно что функциональность, это так же хорошо, и намного проще.
Если даже подклассы не находятся под вашим контролем, часто вы можете просто получить новый класс от каждого, что является. Например:
class Func3Mixin(object):
def func3():
pass
class F3SubClass1(SubClass1, Func3Mixin):
pass
class F3SubClass2(SubClass2, Func3Mixin):
pass
Теперь вы просто построить экземпляры F3SubClass1
вместо SubClass1
. Код, который ожидал экземпляр SubClass1
, может использовать только F3SubClass1
. И утиная печать на Python делает такое «ориентированное на микширование программирование» особенно простым: внутри реализации Func3Mixin.func3
вы можете использовать атрибуты и методы SuperClass
, несмотря на то, что Func3Mixin
сам по себе не статически связан с SuperClass
, потому что вы знаете, что любой объект времени выполнения, который является Func3Mixin
, также будет SuperClass
.
В то же время, даже когда monkeypatching является уместно, это не обязательно лучший ответ. Например, если вы исправляете ошибку в некотором стороннем коде, у этого кода есть хорошая лицензия и исходный репозиторий, который упрощает сохранение ваших собственных патчей, вы можете просто разблокировать его, создать фиксированную копию , и используйте это вместо оригинала.
Кроме того, стоит отметить, что ни один из классов не являются на самом деле можно использовать как списанную любую попытку вызвать любого из методов поднимут TypeError
, потому что они отсутствуют в self
аргумент. Но так, как вы обеимели в func3
, он потерпит неудачу точно так же, как func1
. (И то же самое верно для альтернатив, которые я набросал выше.)
Наконец, все ваши классы здесь классические классы, а не новый стиль, потому что вы забыли сделать SuperClass
наследовать от object
. Если вы не можете изменить SuperClass
, конечно, это не ваша вина, но вы все равно можете ее исправить, сделав ваши подклассы (или Intermediate
) умножить наследование с object
и SuperClass
. (Если вы обращали внимание: да, это означает, что вы можете смешивать в стиле нового стиля. Хотя под обложками вы должны понимать метаклассы, чтобы понять, почему.)
Почему функциональность должна быть добавлена к класс 'A'? Разве это не просто простая старая функция в каком-то другом пространстве имен? «Забивание * всего * в классы», безусловно, не является пифоническим. – millimoose
Да, пожалуйста, объясните свой пример использования – jamylak
Кроме того, если вы используете B и C, вы можете добавить тип посредника, который расширяет суперкласс с требуемой функциональностью, и вместо этого B и C расширят этот класс – mdgeorge