我希望能够基于枚举类创建对象,并使用字典。像这样:
class IngredientType(Enum):
SPAM = auto() # Some spam
BAKE_BEANS = auto() # Baked beans
EGG = auto() # Fried egg
class Ingredient(object):
pass
class Spam(Ingredient):
pass
class BakedBeans(Ingredient):
pass
class Egg(Ingredient):
pass
class IngredientFactory(object):
"""Factory makes ingredients"""
choice = {
IngredientType.SPAM: IngredientFactory.MakeSpam,
IngredientType.BAKED_BEANS: IngredientFactory.MakeBakedBeans,
IngredientType.EGG: IngredientFactory.MakeEgg
}
@staticmethod
def make(type):
method = choice[type]
return method()
@staticmethod
def makeSpam():
return Spam()
@staticmethod
def makeBakedBeans():
return BakedBeans()
@staticmethod
def makeEgg():
return Egg()
但是我得到了错误:
NameError: name 'IngredientFactory' is not defined
由于某种原因无法创建字典。 我哪里出错了?
请您参考如下方法:
Python 不是 Java,不需要所有东西都在一个类中。在这里,您的 IngredientFactory 类没有状态,只有静态方法,因此它实际上只是一个单例命名空间,在 python 中,规范地使用模块作为单例命名空间和纯函数来完成。此外,由于 Python 类已经是可调用的,因此将实例化包装在函数中没有意义。简单、直接的 pythonic 实现是:
# ingredients.py
class IngredientType(Enum):
SPAM = auto() # Some spam
BAKE_BEANS = auto() # Baked beans
EGG = auto() # Fried egg
class Ingredient(object):
pass
class Spam(Ingredient):
pass
class Beans(Ingredient):
pass
class Egg(Ingredient):
pass
_choice = {
IngredientType.SPAM: Spam,
IngredientType.BAKED_BEANS: Beans,
IngredientType.EGG: Egg
}
def make(ingredient_type):
cls = _choice[ingredient_type]
return cls()
和客户端代码:
import ingredients
egg = ingredients.make(ingredients.IngredientType.EGG)
# or much more simply:
egg = ingredients.Egg()
FWIW IngredientType 枚举在这里并没有带来太多,甚至使事情变得更复杂——你可以只使用纯字符串:
# ingredients.py
class Ingredient(object):
pass
class Spam(Ingredient):
pass
class Beans(Ingredient):
pass
class Egg(Ingredient):
pass
_choice = {
"spam": Spam,
"beans": Beans,
"egg": Egg
}
def make(ingredient_type):
cls = _choice[ingredient_type]
return cls()
和客户端代码:
import ingredients
egg = ingredients.make("egg")
或者如果你真的想使用一个Enum,你至少可以通过使用类本身作为枚举的值来摆脱choices dict疯狂物理学家:
# ingredients.py
class Ingredient(object):
pass
class Spam(Ingredient):
pass
class Beans(Ingredient):
pass
class Egg(Ingredient):
pass
class IngredientType(Enum):
SPAM = Spam
BEANS = Beans
EGG = Egg
@staticmethod
def make(ingredient_type):
return ingredient_type.value()
和客户端代码
from ingredients import IngredientType
egg = IngredientType.make(IngredientType.EGG)
但我也真的看不到这里有任何好处
编辑:你提到:
I am trying to implement the factory pattern, with the intent of hiding the creation of objects away. The user of the factory then just handles 'Ingredients' without knowledge of the concrete type
用户仍然必须指定他想要什么样的配料(ingredient_type 参数)所以我不确定我是否理解这里的好处。您的真实用例实际上是什么? (编造/简化示例的问题在于它们并没有讲述整个故事)。
