如何更改基类

3 投票
3 回答
3030 浏览
提问于 2025-04-15 13:53

我有一个类,它是从一个基础类派生出来的,代码行数非常多。

比如:

class AutoComplete(TextCtrl):
    .....

我想做的是修改这个基础类,让它像这样工作:

class AutoComplete(PriceCtrl):
    .....

我需要这两种自动补全的功能,可能还想添加更多的基础类,那么我该如何动态地实现呢?

组合模式本来是个解决办法,但我不想大幅度修改代码。

有没有简单的解决方案呢?

3 个回答

1

你可以修改 __bases__ 这个元组。比如说,你可以添加一个新的基类:

AutoComplete.__bases__ += (PriceCtrl,)

不过一般来说,我建议尽量避免这种小把戏,因为这样很快就会搞得一团糟。

2

你可以使用多重继承来实现这个:

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

不过我还是建议使用之前提到的类工厂方法,缩进一层其实并没有那么麻烦。

7

你可以为你的类创建一个工厂:

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

然后可以这样使用:

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

另一方面,根据你想要实现的目标和你的类的结构,可能AutoComplete是一个混合类,这样你就可以用下面的方式定义 TextAutoComplete

class TextAutocomplete(TextCtrl, AutoComplete):
    pass

撰写回答