Как изменить базовый класс - PullRequest
3 голосов
/ 26 августа 2009

У меня есть класс, который является производным от базового класса, и у меня много строк кода

, например

class AutoComplete(TextCtrl):
    .....

Я хочу изменить базовый класс так, чтобы он работал как

class AutoComplete(PriceCtrl):
    .....

Я использую оба типа автозаполнений и, возможно, хотел бы добавить больше базовых классов, так как я могу сделать это динамически?

Композиция была бы решением, но я не хочу много изменять код.

Есть ли простые решения?

Ответы [ 3 ]

7 голосов
/ 26 августа 2009

У вас может быть фабрика для ваших классов:

def completefactory(baseclass):
    class AutoComplete(baseclass):
        pass
    return AutoComplete

А затем используйте:

TextAutoComplete = completefactory(TextCtrl)
PriceAutoComplete = completefactory(PriceCtrl)

С другой стороны, в зависимости от того, чего вы хотите достичь и как выглядят ваши классы, возможно, AutoComplete должен быть миксином, поэтому вы можете определить TextAutoComplete с помощью:

class TextAutocomplete(TextCtrl, AutoComplete):
    pass
2 голосов
/ 26 августа 2009

Вы можете использовать множественное наследование для этого:

class AutoCompleteBase(object):
    # code for your class
    # remember to call base implementation with super:
    #   super(AutoCompleteBase, self).some_method()

class TextAutoComplete(AutoCompleteBase, TextCtrl):
    pass

class PriceAutoComplete(AutoCompleteBase, PriceCtrl):
    pass

Также есть опция метакласса:

class BasesToSeparateClassesMeta(type):
    """Metaclass to create a separate childclass for each base.
    NB: doesn't create a class but a list of classes."""
    def __new__(self, name, bases, dct):
        classes = []
        for base in bases:
            cls = type.__new__(self, name, (base,), dct)
            # Need to init explicitly because not returning a class
            type.__init__(cls, name, (base,), dct)
            classes.append(cls)
    return classes

class autocompletes(TextCtrl, PriceCtrl):
    __metaclass__ = BasesToSeparateClassesMeta
    # Rest of the code

TextAutoComplete, PriceAutoComplete = autocompletes

Но я бы все-таки предложил уже предложенный подход к фабрике классов: один уровень отступов на самом деле не так уж и значит.

1 голос
/ 26 августа 2009

Вы можете изменить кортеж __bases__. Например, вы можете добавить другой базовый класс:

AutoComplete.__bases__ += (PriceCtrl,)

Но в целом я бы старался избегать таких хаков, это быстро создает ужасный беспорядок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...