在基类python中创建派生类的对象

2024-10-02 12:30:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个名为IDataStream的抽象类,它有一个方法。我为这个名为IMUDataStream的抽象类GPSDataStream创建了两个实现。将来可能会添加IDataStream抽象类的另一个实现。我有另一个名为DataVisualizer的类,它可以可视化由不同的数据流类提取的所有数据

将来,如果我添加IDataStream抽象类的另一个DataStream实现,我不应该修改DataVisualizer类来可视化数据。是否有一种方法可以创建IDataStream类的所有派生类的对象,将其添加到列表中,并遍历该列表,然后使用它调用将提供数据的方法

请注意,我是python和设计模式的新手。努力学习。这可能是一个完全愚蠢的问题,完全疯狂。事实上,我对此有一个要求。如果这可以通过一个设计模式来实现,我要求读者向我指出材料。非常感谢你的帮助。谢谢

#!/usr/bin/env python3

from abc import ABC, abstractmethod

class IDataStream(ABC):
    def get_data(self):
        pass           

class IMUDataStream(IDataStream):
    def __init__(self):
        self.__text = "this is IMU data"

    def get_data(self):
        print(self.__text)

class GPSDataStream(IDataStream):
    def __init__(self):
        self.__text = "this is GPS data"

    def get_data(self):
        print(self.__text)

class DataVisualizer:
    def __init__(self):
        # somehow create objects of all derived classes of IDataStream here and call the get_data() function
        # even if I add another derived class in the future. I should not be modifying the code here

Tags: the方法textselfdatagetinit可视化
2条回答

首先,您可能希望方法get_data返回数据,而不是打印它(否则它将自己进行可视化)。这可能是你想要的。下面的代码将计算出IDataStream的所有子类,实例化类的实例(如果它不是抽象类),调用实例上的方法get_data,并将返回值附加到list中:

#!/usr/bin/env python3

from abc import ABC, abstractmethod

class IDataStream(ABC):
    @abstractmethod # you probably ment to add this
    def get_data(self):
        pass

class IMUDataStream(IDataStream):
    def __init__(self):
        self.__text = "this is IMU data"

    def get_data(self):
        return self.__text

class GPSDataStream(IDataStream):
    def __init__(self):
        self.__text = "this is GPS data"

    def get_data(self):
        return self.__text


def is_abstract(cls):
    return bool(getattr(cls, "__abstractmethods__", False))


def get_all_non_abstract_subclasses(cls):
    all_subclasses = []
    for subclass in cls.__subclasses__():
        if not is_abstract(subclass):
            all_subclasses.append(subclass)
        all_subclasses.extend(get_all_non_abstract_subclasses(subclass))
    return all_subclasses


class DataVisualizer:
    def __init__(self):
        data =  [cls().get_data() for cls in get_all_non_abstract_subclasses(IDataStream)]
        print(data)

dv = DataVisualizer()

印刷品:

['this is IMU data', 'this is GPS data']

您所要求的是能够找到内存中的所有实例化对象,然后仅为特定类/子类/父类/任何对象对它们进行筛选,请看一下关于如何从内存中获取所有当前对象和方法的stack-overflow question

也就是说。。。任何时候,当你不得不问自己如何在内存中全局查找某个事物的所有实例时,你都应该停下来问自己(看起来你做到了,很荣幸),有没有更好/更简单的方法

大多数情况下,您希望使数据可视化工具独立,这样它只使用数据流(在构建过程中指定),请参见以下内容:

ds = myDataStream()

vis = myDataVisualizer(ds)
vis.show() # or whatever

ds = myDataStream()

vis = myDataVisualizer()
vis.show(ds)

如果您希望您的数据可视化工具在运行时是数据不可知的(比如数据来自多个源),那么您有两个选择。添加用于删除和添加数据源的方法,或者,您可以使用类似于使用Queues and Processes的生产者-消费者模式的方法将它们链接在一起(我就是这样做的)

但是,如果您真的必须完全管理自己的内存(比如通过映射、堆或其他方式)。还有一些设计模式可以帮助您:

  • 工厂
  • 抽象工厂
  • 装饰师
  • 或者其他人,看一下refactoring.guru上的目录

相关问题 更多 >

    热门问题