I want to be able to create objects based on an enumeration class, and use a dictionary. Something like this:
JavaScript
x
41
41
1
class IngredientType(Enum):
2
SPAM = auto() # Some spam
3
BAKE_BEANS = auto() # Baked beans
4
EGG = auto() # Fried egg
5
6
class Ingredient(object):
7
pass
8
class Spam(Ingredient):
9
pass
10
class BakedBeans(Ingredient):
11
pass
12
class Egg(Ingredient):
13
pass
14
15
16
class IngredientFactory(object):
17
"""Factory makes ingredients"""
18
19
choice = {
20
IngredientType.SPAM: IngredientFactory.MakeSpam,
21
IngredientType.BAKED_BEANS: IngredientFactory.MakeBakedBeans,
22
IngredientType.EGG: IngredientFactory.MakeEgg
23
}
24
25
@staticmethod
26
def make(type):
27
method = choice[type]
28
return method()
29
30
@staticmethod
31
def makeSpam():
32
return Spam()
33
34
@staticmethod
35
def makeBakedBeans():
36
return BakedBeans()
37
38
@staticmethod
39
def makeEgg():
40
return Egg()
41
But I get the error:
JavaScript
1
2
1
NameError: name 'IngredientFactory' is not defined
2
For some reason the dictionary can’t be created. Where am I going wrong here?
Advertisement
Answer
After looking at Bruce Eckel’s book I came up with this:
JavaScript
1
51
51
1
#Based on Bruce Eckel's book Python 3 example
2
# A simple static factory method.
3
from __future__ import generators
4
import random
5
from enum import Enum, auto
6
7
class ShapeType(Enum):
8
CIRCLE = auto() # Some circles
9
SQUARE = auto() # some squares
10
11
class Shape(object):
12
pass
13
14
class Circle(Shape):
15
def draw(self): print("Circle.draw")
16
def erase(self): print("Circle.erase")
17
18
class Square(Shape):
19
def draw(self): print("Square.draw")
20
def erase(self): print("Square.erase")
21
22
class ShapeFactory(object):
23
24
@staticmethod
25
def create(type):
26
#return eval(type + "()") # simple alternative
27
if type in ShapeFactory.choice:
28
return ShapeFactory.choice[type]()
29
30
assert 0, "Bad shape creation: " + type
31
32
choice = { ShapeType.CIRCLE: Circle,
33
ShapeType.SQUARE: Square
34
}
35
36
# Test factory
37
# Generate shape name strings:
38
def shapeNameGen(n):
39
40
types = list(ShapeType)
41
42
for i in range(n):
43
yield random.choice(types)
44
45
shapes =
46
[ ShapeFactory.create(i) for i in shapeNameGen(7)]
47
48
for shape in shapes:
49
shape.draw()
50
shape.erase()
51
This gets the user to select a class type from the enumeration, and blocks any other type. It also means user’s are less likely to write ‘bad strings’ with spelling mistakes. They just use the enums. The output from the test is then, something like this:
JavaScript
1
15
15
1
Circle.draw
2
Circle.erase
3
Circle.draw
4
Circle.erase
5
Square.draw
6
Square.erase
7
Square.draw
8
Square.erase
9
Circle.draw
10
Circle.erase
11
Circle.draw
12
Circle.erase
13
Square.draw
14
Square.erase
15