【问题标题】:How to change baseclass如何更改基类
【发布时间】:2010-11-22 23:35:40
【问题描述】:

我有一个派生自基类的类,并且有很多行代码

例如

class AutoComplete(TextCtrl):
    .....

我想要做的是改变基类,让它像这样工作

class AutoComplete(PriceCtrl):
    .....

我对这两种类型的 AutoCompletes 都有使用,并且可能想要添加更多的基类,那么我该如何动态地做到这一点?

组合本来是一个解决方案,但我不想大量修改代码。

任何简单的解决方案?

【问题讨论】:

    标签: python dynamic class


    【解决方案1】:

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

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

    然后使用:

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

    另一方面,根据您想要实现的目标以及您的类的外观,AutoComplete 可能是一个 mixin,因此您可以使用以下方式定义 TextAutoComplete

    class TextAutocomplete(TextCtrl, AutoComplete):
        pass
    

    【讨论】:

    • 我正在考虑类似的行,但它需要我缩进整个代码,正如我所说的很多行,反对看起来微不足道,但我希望我不必缩进它
    • 不缩进:将隐藏在模块顶层的类声明为_TextAutoComplete等,然后使用工厂。
    • @Anurag,在块模式下使用vim,或者sed,真的很容易reindent(你应该学会怎么做,在python编程时非常有用)
    • @tonfa 谢谢,我知道如何缩进代码,但我只是不想嵌套 1000 行的整个类代码“平面比嵌套更好。”
    【解决方案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
    

    但我仍然建议使用已经建议的类工厂方法,一级缩进真的没什么大不了的。

    【讨论】:

      【解决方案3】:

      您可以修改 __bases__ 元组。例如,您可以添加另一个基类:

      AutoComplete.__bases__ += (PriceCtrl,)
      

      但总的来说,我会尽量避免这种黑客攻击,它很快就会造成可怕的混乱。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-30
        • 2015-08-28
        • 1970-01-01
        • 2014-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多