Python: добавить родительский класс в класс после начальной оценки - PullRequest
7 голосов
/ 14 сентября 2011

Общий вопрос по Python

Я импортирую библиотеку Python (назовите animals.py) со следующей структурой класса:

class Animal(object): pass

class Rat(Animal): pass

class Bat(Animal): pass

class Cat(Animal): pass

...

Я хочу добавить родительский класс (Pet) для каждого из классов видов (Rat, Bat, Cat, ...);однако, я не могу изменить фактический источник библиотеки, которую я импортирую, поэтому это должно быть изменение во время выполнения.

Кажется, работает следующее:

import animals

class Pet(object): pass

for klass in (animals.Rat, animals.Bat, animals.Cat, ...): 
    klass.__bases__ = (Pet,) + klass.__bases__

Это лучший способ внедрить родительский класс в дерево наследования в Python без внесения изменений в определение источника изменяемого класса?

Мотивирующие обстоятельства

Я пытаюсь привить упорство в большую библиотеку, которая контролирует лабораторное оборудование.Возиться с этим невозможно.Я хочу дать ZODB Persistent попытку.Я не хочу писать библиотеку оболочек mixin / фасадов, потому что я имею дело с более чем 100 классами и множеством импортов в коде моего приложения, которые необходимо обновить.Я тестирую варианты, взламывая только мою точку входа: настраивая БД, внося исправления, как показано выше (но вытягивая классы видов с интроспекцией в модуле животных вместо явного перечисления), затем закрывая БД при выходе.

Mea Culpa / Request

Это намеренно общий вопрос.Меня интересуют разные подходы к инъекции родителя и комментарии о плюсах и минусах этих подходов.Я согласен с тем, что такого рода чиканеринг во время выполнения может привести к действительно запутанному коду.Если я остановлюсь на ZODB, я сделаю что-то явное.На данный момент, как обычный пользователь python, меня интересует общий случай.

Ответы [ 2 ]

1 голос
/ 04 января 2012

Ваш метод в значительной степени заключается в том, как сделать это динамически. Реальный вопрос: что добавляет этот новый родительский класс? Если вы пытаетесь вставить свои собственные методы в цепочку методов, которая существует в уже существующих классах, и они не были написаны должным образом, вы не сможете; если вы добавляете оригинальные методы (например, интерфейсный слой), то вместо этого вы можете просто использовать функции.

Я тот, кто принимает динамическую природу Python и не будет иметь проблем с использованием представленного вами кода. Убедитесь, что у вас есть хорошие модульные тесты (динамические или нет;) и что изменение дерева наследования действительно позволяет вам делать то, что вам нужно, и наслаждаться Python!

0 голосов
/ 14 сентября 2011

Вы должны изо всех сил стараться не делать этого. Это странно и, скорее всего, закончится слезами.

Как упоминает @agf, вы можете использовать Pet как миксин. Если вы расскажете нам больше о том, почему вы хотите вставить родительский класс, мы поможем вам найти более подходящее решение.

...