“继承但扩展选项的枚举列表”的建议模式

Suggested pattern for "inheriting but extending Enum list of options"

提问人:Jagerber48 提问时间:10/26/2022 最后编辑:Jagerber48 更新时间:10/27/2022 访问量:46

问:

我有一个类,它运行然后解析结果数据以确定 的 .可以是类似 或 .我选择用枚举来表示这些可能的任务状态。这很好。但是,我正在子类化,更专业的类应该有更多的任务状态可供他们使用。例如,a 还应具有可用状态。实现这一点的好方法是什么?TaskTasktask_statustask_status'SUCCESS''FAILURE'TaskTaskWithRetryRETRY

示例代码:

from enum import Enum

class TaskStatus(Enum):
    SUCCESS = 'SUCCESS'
    FAILURE = 'FAILURE'

class Task:
    ...
    def run():
        ...
        self.data = ...
        self.task_status = self.parse_data(self.data)

    def parse_data(self, data)
        if data is good:
            task_status = TaskStatus.SUCCESS
        elif data is bad:
            task_status = TaskStatus.FAILURE
        else:
            raise ValueError('Cannot parse data')
        return task_status

class TaskWithRetry(Task):
    def parse_data(self, data)
        if data is good:
            task_status = TaskStatus.SUCCESS
        elif data is bad:
            task_status = TaskStatus.FAILURE
        elif data is kind of bad:
(*)         task_status = TaskStatus.RETRY
        else:
            raise ValueError('Cannot parse data')
        return task_status

这里的问题是该行将失败,因为不在 .我可能的解决方案是:(*)RETRYTaskStatus

  • 添加到 .这样做的问题是,假设我正在研究.我不想看到相关的.RETRYTaskStatusEnumSubTask ATaskStatus.X,Y,ZSubTask D
  • 为每个子任务创建一个专用的子任务。这将导致任何人都可以拥有的共享和选项的大量重复,并且定义任何新的 .SubTaskStatusEnumSUCCESSFAILURETaskSubTask
  • 我的第一个想法是子类化,这样我就可以固有并根据需要为每个选项添加新选项,但我了解到,出于大概充分的理由,你不能像这样子类然后定义新字段。TaskStatusSubTaskStatusSUCCESSFAILURESubTaskEnum
  • 如果我放弃这种方法,我可以像在模块级别一样定义字符串。然后,我可以定义新的字符串,例如在模块中的适当位置。这类似于向枚举添加所有可能性,但至少新状态将与相关类接近。EnumSUCCESS = 'SUCCESS'RETRY = 'RETRY'TaskStatus
  • 就像前面的想法一样,但可能更好:任务状态可以定义为类属性字符串。这种方式将为 的任何子项定义,并且新状态将是子项的类属性。这个想法似乎没问题,但是我如何明确指出这些字符串是可能的任务状态呢?self.SUCCESSTask

还要记住,此代码的使用方式是用户/开发人员定期对 Task 进行子类化,并且需要非常简单地了解如何根据需要为特定的新任务添加新任务状态。Task

Python 枚举

评论


答: 暂无答案