繁体   English   中英

Python 创建派生实例 class

[英]Python create instance of derived class

我想要抽象 class Task 和一些派生类,如 TaskA、TaskB,...我需要 static Task 中的方法来获取所有任务并返回它们的列表。 但问题是我必须以不同的方式获取每项任务。 我希望任务是通用的,所以当我创建新的 class 例如 TaskC 时,它应该可以在不更改 class 任务的情况下工作。 我应该使用哪种设计模式? 假设每个派生任务都有其唯一 ID 的装饰器,我正在寻找 function,它将通过 ID 找到 class 并创建它的实例。 python怎么办?

有几种方法可以实现这一点。

第一个也是最简单的方法是使用__new__方法作为工厂来决定应该返回哪个子类。

class Base:
    UUID = "0"
    def __new__(cls, *args, **kwargs):
        if args == "some condition":
            return A(*args, **kwargs)
        elif args == "another condition":
            return B(*args, **kwargs)

class A(Base):
    UUID = "1"

class B(Base):
    UUID = "2"
    
instance = Base("some", "args", "for", "the", condition=True)

在这个例子中,如果你想确保 class 被 uuid 选择。 你可以替换 if 条件来阅读类似的内容

if a.UUID == "an argument you passed":
    return A

但它并不是很有用。 既然您知道特定的 UUID,那么您不妨不必费心浏览该界面。

因为我不知道你想要装饰器做什么,所以我想不出集成它的方法。

编辑以解决注意事项:

如果你巧妙地表达你的表情,你不需要每次都更新它。

假设定义因素来自配置文件,上面写着“使用 class B”

for sub_classs in self.__subclasses__():
    if sub_class.UUID == config.uuid:
        return sub_class(*args, **kwargs) # make an instance and return it

这样做的问题是 uuid 对我们人类没有用。 如果我们使用config.name来替换我们在示例中有 uuid 的每个地方,将会更容易理解

我为此奋斗了很多时间,这正是我想要的:

def class_id(id:int):
    def func(cls):
        cls.class_id = lambda : id
        return cls
    return func

def find_subclass_by_id(cls:type, id:int) -> type:
    for t in cls.__subclasses__():
        if getattr(t, "class_id")() == id:
            return t


def get_class_id(obj)->int:
    return getattr(type(obj), "class_id")()



class Task():
    def load(self, dict:Dict) -> None:
        pass

    @staticmethod
    def from_dict(dict:Dict) -> 'Task':
        task_type = int(dict['task_type'])
        t = find_subclass_by_id(Task, task_type)
        obj:Task = t()
        obj.load(dict)
        return obj


    @staticmethod
    def fetch(filter: Dict):
        return [Task.from_dict(doc) for doc in list_of_dicts]

@class_id(1)
class TaskA(Task):
     def load(self, dict:Dict) -> None:
        ...
     ...
 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM