如何使枚举指向 class

how to make an enum point to a class

假设我有这个枚举用于存储所有不同的实体类型

class Entities(Enum):
    TREE = auto()
    ROCK = auto()
    FLOWER = auto()

我想创建一个函数,它采用这些(TREE、ROCK...)枚举之一,并且知道枚举对应于我拥有的 class。 例如:

def myFunc(EntityType):
    return type(EntityType)

print(myFunc(Entities.ROCK))
>>>ROCK (where ROCK is an instance of the ROCK class)

如果有办法做到这一点,有没有一种甚至可以初始化 class 例如:

def myFunc(EntityType):
    myObj = EntityType(pos=(0,0))
    return myObj

如果您放弃 auto 并使用 classes 本身作为 Entities 的值会怎么样?假设 TreeRockFlower 是您的 classes 的名称:

class Entities(Enum):
    TREE = Tree
    ROCK = Rock
    FLOWER = Flower

此处Entities.TREE.valueTree的class构造函数。

这里有一个 Kyle Parsons 回答的例子:

from enum import Enum
from dataclasses import dataclass

@dataclass
class Animal:
    name: str
    age: int
    type: str = None

@dataclass
class Cat(Animal):
    type: str = 'Cat'

@dataclass
class Dog(Animal):
    type: str = 'Dog'


class AnimalType(Enum):
    DOG = Dog
    CAT = Cat


def get_animal(type: Enum, name: str, age: int):
    return type.value(name, age)

print(get_animal(AnimalType.CAT, 'Peter', 12))

您可以向 Enum 对象添加属性,或者您可以使用 dict 映射 Enum。还有其他选项,但这些似乎最简单。

假设您有 classes TreeRockFlower 等,对应于 Enum 的值:

class Tree:
    def __init__(self, height, coords):
        pass

class Rock:
    def __init__(self, coords):
        pass

class Flower:
    def __init__(self, color, iscarnivore, coords):
        pass

我专门展示了一个扩展版本,其中每个 class 都有不同的初始值设定项和一组不同的默认值。如果都相同,则使用现有答案。

选项 1 是这样定义枚举:

class Entities(Enum):
    TREE = (Tree, 100, (0, 0))
    ROCK = (Rock, (0, 0))
    FLOWER = (Flower, 'red', True, (0, 0))

    def __new__(cls, t, *args):
        obj = object.__new__(cls)
        obj._value_ = len(cls.__members__) + 1
        obj.type = t
        obj.defaults = args
        return obj

    def init(self):
        return self.type(*self.defaults)

现在,my_func 只是枚举本身的 init 方法:

>>> FLOWER.init() # Calls Flower('red', False, (0, 0))

第二个选项是将 Enum 成员映射到 class:

cmap = {
    Entitites.TREE: (Tree, 100, (0, 0)),
    Entitites.ROCK: (Rock, (0, 0)),
    Entitites.FLOWER: (Flower, 'red', True, (0, 0)),
}

def my_func(entity):
    t, *args = cmap[entity]
    return t(*args)