Python objects already store attributes in a dict so what is the point of using yet another dict here ? Just store your attributes the usual way (using properties where it makes sense), and build the desc
dict dynamically when you need it.
class SomeClass(object):
HAIRCOLORS = set(['blonde', 'brunette', 'brown', 'black', 'auburn', 'red'])
EYECOLORS = set(['green', 'blue', 'brown', 'gray'])
def __init__(self, haircolor="blond", eyecolor="green"):
self.haircolor = haircolor
self.eyecolor = eyecolor
self.height = 1.55 # you didn't mention any validation here
@property
def haircolor(self):
return self._haircolor
@haircolor.setter
def haircolor(self, color):
color = color.lower()
if color not in self.HAICOLORS:
raise ValueError("'%s' is not a valid hair color" % color)
self._haircolor = color
# same thing for eyecolor
@property
def desc(self):
return dict(
haircolor=self.haircolor,
eyecolor=self.eyecolor,
height=self.height)
If this is a reccuring pattern you can eventually write your own descriptor:
class ChoiceDescriptor(object):
def __init__(self, key, choices):
self.key = key
self.storage = "_%s" % key
self.choices = set(choices)
def __get__(self, instance, cls=None):
if instance is None:
return self
return getattr(instance, self.storage)
def __set__(self, instance, value):
value = value.lower()
if value not in self.choices:
raise ValueError(
"'%s' is not a valid value for '%s'" % (value, self.key))
setattr(instance, self.storage, value)
class SomeClass(object):
haircolor = ChoiceDescriptor("haircolor",
['blonde', 'brunette', 'brown', 'black', 'auburn', 'red'])
eyecolor = ChoiceDescriptor("eyecolor",
['green', 'blue', 'brown', 'gray'])