为任何通用父类定义的子类[重复]

Posted

技术标签:

【中文标题】为任何通用父类定义的子类[重复]【英文标题】:Child class defined for any generic parent class [duplicate] 【发布时间】:2022-01-10 15:22:11 【问题描述】:

我想定义一个简单的子类,它继承了父类的所有方法并引入了一些新方法。警告:我不想指定父类是什么,因为我希望这个子类与广泛的类兼容。有没有办法做到这一点?

如果不是,那么创建一个继承任何其他类的所有方法并引入新方法的新类的最佳方法是什么?

【问题讨论】:

看看 mixins。 【参考方案1】:

您要查找的内容通常称为mixin。以这些课程为例。

class FooBase:
    def data(self):
        return "foo"


class BarBase:
    def data(self):
        return "bar"

两者都定义了data 方法,但它们本身是不同的类。如果我们想提供一些可以打印来自 data 的值的 mixin 类,我们可以这样做:

from abc import ABC, abstractmethod


class PrintDataMixin(ABC):
    @abstractmethod
    def data(self):
        pass

    def print_data(self):
        print(self.data())

这里我们说PrintDataMixin mixin 可以应用于任何实现了data 方法的类。 FooBaseBarBase 可以定义完全不同的方法集,但只要定义了 data 方法,它们就可以满足 PrintDataMixin 的使用。

使用此 mixin 扩展 FooBaseBarBase 的示例用法:

class FooImpl(FooBase, PrintDataMixin):
    pass


class BarImpl(BarBase, PrintDataMixin):
    pass


FooImpl().print_data()
BarImpl().print_data()
foo
bar

更新:

您可以尝试更通用地执行此操作,但总的来说,我发现这样的动态类很难使用,尤其是在您需要调试应用程序时。这也让 mypy 等静态分析器更难确定您是否正确使用了类。

当类在源代码中定义良好时,更容易确定发生了什么。

要动态创建应用了 mixin 的类,您可以执行以下操作:

def class_of(*cls):
    class NewClass(*cls):
        pass
    return NewClass


class_of(BaseClass, MixinClass)(*args, **kwargs).print_data()

【讨论】:

对,但即使 mixin 仍然强制我列出每个父类,对吗?有没有办法避免这种情况?换句话说,我可以创建一个类 Child(generic_parent),只有当我实例化一个对象时,我才决定具体的父类? @DaltonicD 我建议不要这样做,但我更新了你可以做的。 谢谢!你说你反对它。那么,定义一个将所需方法添加到实例化对象的函数而不是构建一个新类会更好吗? @DaltonicD 这似乎是不必要的复杂性,尤其是当创建一个新类很容易时(并且从这个例子中已经非常简洁)。这是个人意见,但如果我可以使用更基本的结构,我会尽可能避免继承。为什么方法需要在类上?如果方法不需要特定于类,那么首先将它放在类上没有多大意义。您始终可以创建一个接受具有特定接口的类实例的无状态函数。使类构造动态化只会给复杂性增加一层洋葱。

以上是关于为任何通用父类定义的子类[重复]的主要内容,如果未能解决你的问题,请参考以下文章

20145235 《Java程序设计》第4周学习总结

20145207 2016-2017-2 《Java程序设计》第4周学习总结

以父类和子类作为参数的方法重载[重复]

PHP - 子类没有从父类继承[重复]

Typescript - 为非常通用的功能定义接口[重复]

自动初始化父类和子类中的成员变量[重复]