【问题标题】:how to make an enum point to a class如何使枚举指向一个类
【发布时间】:2021-09-05 16:19:25
【问题描述】:

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

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

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

def myFunc(EntityType):
    return type(EntityType)

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

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

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

【问题讨论】:

    标签: python class enums


    【解决方案1】:

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

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

    这里Entities.TREE.valueTree 的类构造函数。

    【讨论】:

    • 除非所有目标都有相同的初始化程序,否则这对初始化任何东西都没有帮助。
    【解决方案2】:

    这是凯尔·帕森斯回答的一个例子:

    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))
    

    【讨论】:

    • 这只是强调所有目标类型必须具有相同的构造函数。
    【解决方案3】:

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

    假设您有 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
    

    我专门展示了一个扩展版本,其中每个类都有不同的初始化程序和一组不同的默认值。如果它们都相同,请使用现有答案。

    选项 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 成员映射到类:

    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)
    

    【讨论】:

      猜你喜欢
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 2022-12-22
      • 1970-01-01
      • 2021-12-19
      相关资源
      最近更新 更多