按成员值从python枚举中选择

2024-09-30 14:36:12 发布

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

如何获取在给定但未知字段上满足条件的枚举类的所有实例

我有以下三个派生自Enum的类,两个简单类(VariableTypeVariableCategory)和一个,其中实例实际将内容存储在字段(Variable)中

class VariableCategory(Enum):
    SHORT = auto()
    MEDIUM = auto()
    LONG = auto()

class VariableType(Enum):
    ONE = auto()
    TWO = auto()

class Variable(Enum):
    A = ('Variable A',
           VariableCategory.SHORT,
           VariableType.ONE,
           1)
    B = ('Variable B',
           VariableCategory.MEDIUM,
           VariableType.TWO,
           2)
    C = ('Variable V',
           VariableCategory.SHORT,
           VariableType.TWO,
           3)

    def __init__(self, name: str, variable_category: VariableCategory, variable_type: VariableType,
                 number:int) -> None:
        self.name = name
        self.variable_category = variable_category
        self.variable_type = variable_type
        self.number = number

现在,我想创建一个类函数,它可以接受类型为VariableTypeVariableCategory的任意参数,并返回Variable的所有对应实例:

@classmethod
def by_x(cls, x: Union[VariableType, VariableCategory]):
    # something like return [cls[member] for member in cls.__members__ if x in cls[member]]

例如,给定一个VariableType,相应的Variable实例如下:

>>> Variable.by_x(VariableType.ONE)
    [Variable.A]
>>> Variable.by_x(VariableType.TWO)
    [Variable.B, Variable.C]
>>> Variable.by_x(VariableCategory.SHORT)
    [Variable.A, Variable.C]
>>> Variable.by_x(VariableCategory.MEDIUM)
    [Variable.B]
>>> Variable.by_x(VariableCategory.LONG)
    []

我还知道,我可以对Variable枚举的一个字段使用更具体的函数:

@classmethod
def by_variable_type(cls, variable_type: VariableType) -> List['Variable']:
    return [cls[member] for member in cls.__members__ if cls[member].variable_type == variable_type]

但是,我不知道如何只生成一个通用函数,而不是许多特定函数(也就是说,不检查参数的类型并相应地调用特定的解决方案)


Tags: 实例函数selfautobytypeenumvariable
2条回答

此解决方案满足您的需要

get_by_values类方法可以接收一个列表,或者包含您想要满足的任何值组合的列表列表。它保证只返回完全满足您传入的组合之一的成员。它返回setEnum成员,因此保证没有任何重复。如果在返回中使用列表,则会得到与传入的每个参数对应的有序结果

Variable成员已经有了Variable.name您可以用它们声明。如果你想要更具表现力的东西,我会选择__str____init__,也许会结合VariableCategory.nameVariableType.name

from enum import Enum, auto


class VariableCategory(Enum):
    SHORT = auto()
    MEDIUM = auto()
    LONG = auto()


class VariableType(Enum):
    ONE = auto()
    TWO = auto()


class Variable(Enum):
    A = VariableCategory.SHORT, VariableType.ONE
    B = VariableCategory.MEDIUM, VariableType.TWO
    C = VariableCategory.SHORT, VariableType.TWO

    def __init__(self, variable_category: VariableCategory, variable_type: VariableType):
        self.variable_category = variable_category
        self.variable_type = variable_type

    def in_value(self, argument):
        if set(argument).issubset(set(self.value)):
            return self

    @classmethod
    def get_by_values(cls, *args):
        return {member for member in cls
                if member in {member.in_value(arg) for arg in args}}


first = [VariableCategory.SHORT, VariableType.ONE]
second = [VariableCategory.SHORT]

print(*Variable.get_by_values(first, second))
# Variable.A Variable.C

print(*Variable.get_by_values([VariableCategory.MEDIUM]))
# Variable.B

print(*Variable.get_by_values([VariableType.TWO]))
# Variable.B Variable.C

编辑:将的替换为集合理解。扩展的for部分如下所示:

def in_value(self, argument):

    for element in argument:
        if element not in self.value:
            return False

    return True

@classmethod
def get_by_values(cls, *args):
    result = list()

    for one_member in Variable:
        for argument in args:
            if one_member.in_value(argument):
                if one_member not in result:
                    result.append(one_member)

    return result
    @classmethod
    def by_x(cls, criterion):
        return [
                m
                for m in cls
                if m.variable_category == criterion
                    or m.variable_type == criterion
                    ]

另一方面,您不能将self.name赋值给它,因为它会引发AttributeError

相关问题 更多 >