簡體   English   中英

在基類中創建派生類的對象 - python

[英]Creating objects of derived class in base class - python

我有一個名為 IDataStream 的抽象類,它有一個方法。 我為這個名為 IMUDataStream、GPSDataStream 的抽象類創建了兩個實現。 將來我可能會添加 IDataStream 抽象類的另一個實現。 我有另一個名為 DataVisualizer 的類,它可視化由不同 DataStream 類提取的所有數據。

將來如果我添加 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

您要問的是能夠找到內存中的所有實例化對象,然后僅針對特定類/子類/父類/任何內容過濾它們,請查看有關如何獲取所有內容的堆棧溢出問題內存中的當前對象和方法。

就是說......任何時候你必須問自己如何在內存中找到全局的所有實例,你應該停下來問問(這看起來你做了,所以榮譽)有沒有更好/更簡單的方法?

大多數情況下,您希望使數據可視化器獨立,以便它只使用數據流(在構建期間指定),見下文:

ds = myDataStream()

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

或者

ds = myDataStream()

vis = myDataVisualizer()
vis.show(ds)

如果您希望您的數據可視化工具在運行時與數據無關(例如數據來自多個來源),那么您有幾個選擇。 添加用於刪除和添加數據源的方法,或者,您可以使用諸如使用隊列和進程的生產者-消費者模式之類的東西將它們鏈接在一起(我就是這樣做的)。

但是,如果您真的必須完全管理自己的內存(例如通過映射、堆或其他任何方式)。 然后有一些設計模式可以幫助你:

  • 工廠
  • 抽象工廠
  • 裝飾器
  • 或者也許是其他人,請查看refactoring.guru上的目錄

首先,您可能希望方法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']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM