如何使枚举指向 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
的值会怎么样?假设 Tree
、Rock
和 Flower
是您的 classes 的名称:
class Entities(Enum):
TREE = Tree
ROCK = Rock
FLOWER = Flower
此处Entities.TREE.value
是Tree
的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 Tree
、Rock
、Flower
等,对应于 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)
假设我有这个枚举用于存储所有不同的实体类型
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
的值会怎么样?假设 Tree
、Rock
和 Flower
是您的 classes 的名称:
class Entities(Enum):
TREE = Tree
ROCK = Rock
FLOWER = Flower
此处Entities.TREE.value
是Tree
的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 Tree
、Rock
、Flower
等,对应于 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)