如果将基类的可选功能存储在二级类中,二级类是否应该继承基类?

map*_*apf 8 python multiple-inheritance method-resolution-order

我知道标题可能有点混乱,所以让我举个例子。假设您有一个基类Base,它旨在被子类化以创建更复杂的对象。但是您还有一些可选功能,您不需要每个子类都需要这些功能,因此您将它放在一个二级类中OptionalStuffA,该二级类始终打算与基类一起进行子类化。你也应该让那个次要类成为 的子类Base吗?

这当然是唯一相关,如果你有一个以上的OptionalStuff班,你想给他们以不同的方式结合起来,否则你不需要子类均BaseOptionalStuffA(,只是有OptionalStuffA成为的一个子类Base,所以你只需要在子类OptionalStuffA)。我Base知道如果从Base.

下面是一个示例场景。我还将QObject该类作为“第三方”令牌类放入该类,其功能对于其中一个辅助类工作是必需的。我在哪里子类化它?下面的例子显示了我到目前为止是如何做到的,但我怀疑这是要走的路。

from PyQt5.QtCore import QObject

class Base:
    def __init__(self):
        self._basic_stuff = None

    def reset(self):
        self._basic_stuff = None


class OptionalStuffA:
    def __init__(self):
        super().__init__()
        self._optional_stuff_a = None

    def reset(self):
        if hasattr(super(), 'reset'):
            super().reset()
        self._optional_stuff_a = None

    def do_stuff_that_only_works_if_my_children_also_inherited_from_Base(self):
        self._basic_stuff = not None


class OptionalStuffB:
    def __init__(self):
        super().__init__()
        self._optional_stuff_b = None

    def reset(self):
        if hasattr(super(), 'reset'):
            super().reset()
        self._optional_stuff_b = None

    def do_stuff_that_only_works_if_my_children_also_inherited_from_QObject(self):
        print(self.objectName())


class ClassThatIsActuallyUsed(Base, OptionalStuffA, OptionalStuffB, QObject):
    def __init__(self):
        super().__init__()
        self._unique_stuff = None

    def reset(self):
        if hasattr(super(), 'reset'):
            super().reset()
        self._unique_stuff = None
Run Code Online (Sandbox Code Playgroud)

wet*_*ler 2

我从你的问题中可以得到的是,你希望根据不同的条件拥有不同的功能和属性,这听起来像是使用 MetaClass 的好理由。这完全取决于你的每个类的复杂程度,以及你正在构建什么,如果它是针对某些库或 API,那么如果使用得当,MetaClass 可以发挥神奇作用。

MetaClass 非常适合根据某种条件向类添加函数和属性,您只需将所有子类函数添加到一个元类中,然后将该 MetaClass 添加到您的主类中

从哪里开始

您可以在此处阅读有关 MetaClass 的信息,也可以在此处观看。在您对 MetaClass 有更好的了解之后,请从此处此处查看 Django ModelForm 的源代码,但在此之前,先简要了解一下Django Form从外部如何工作,这将使您了解如何实现它。

这就是我将如何实现它。

#You can also inherit it from other MetaClass but type has to be top of inheritance
class meta_class(type):
    # create class based on condition

    """
    msc: meta_class, behaves much like self (not exactly sure).
    name: name of the new class (ClassThatIsActuallyUsed).
    base: base of the new class (Base).
    attrs: attrs of the new class (Meta,...).
    """

    def __new__(mcs, name, bases, attrs):
        meta = attrs.get('Meta')
        if(meta.optionA){
            attrs['reset'] = resetA
        }if(meta.optionB){
            attrs['reset'] = resetB
        }if(meta.optionC){
            attrs['reset'] = resetC
        }
        if("QObject" in bases){
            attrs['do_stuff_that_only_works_if_my_children_also_inherited_from_QObject'] = functionA
        }
        return type(name, bases, attrs)


class Base(metaclass=meta_class): #you can also pass kwargs to metaclass here

    #define some common functions here
    class Meta:
        # Set default values here for the class
        optionA = False
        optionB = False
        optionC = False


class ClassThatIsActuallyUsed(Base):
    class Meta:
        optionA = True
        # optionB is False by default
        optionC = True
Run Code Online (Sandbox Code Playgroud)

编辑:详细说明如何实现元类。