On 13/02/13 06:45, Barry Warsaw wrote: [...]
IMHO, none of these approach the simplicity and explicitness of this API:
class Color(Enum): RED = 1 GREEN = 2 BLUE = 3
class FieldType(Enum): BINARY = 1 AUTOINC = 2 NULLABLE = 4
The savings in a few characters, does not (again IMHO) make up for all the magic and implicitness you have to guess at with the top versions.
I also don't find much value in the 'unique' style, which seem like they're just another way to name string constants. Here though, you could argue that the DRY principle at least makes them interesting, since IIUC, the explicit alternative would be
class Geometry: LEFT = 'left' RIGHT = 'right' TOP = 'top' # ... and so on ...
I just wouldn't call these "enums" though. ;) Again, being a little more explicit seems like a win, or at least not so bad.
My perspective from the peanut gallery is, not so. That "little more" explicitness actually raises the barrier to using enums enough that they are underused. In my experience, good practice or not, too people avoid defining enum-like constants: LEFT = 'left' RIGHT = 'right' ... and just embed the string literals in their code instead. def move(distance, direction): if direction == 'left': ... It's hard to avoid the "magic constant" anti-pattern, and too easy to fall into the bad habit. Speaking as an ex-Pascal programmer, I really miss the simplicity of creating enumerated types. type units = (inches, feet, furlongs, miles); relationship = (parent, sibling, child); which would correspond to Tim's suggestion: class units(Enum): INCHES, FEET, FURLONGS, MILES class relationship(Enum): PARENT, SIBLING, CHILD I would use that, since I don't really care what the values of the enums are. All I care is: - they're unique within a type/class; - they print like their name (e.g. FEET not 1); - (optional) they can combine as bitmasks. Not having to set their value explicitly is a *good thing*. If I don't know the underlying value, I'm not tempted to do this: some_func(42, unit=1) # should be unit=FEET But if I had to use something like this: class units(Enum): INCHES = val() FEET = val() FURLONGS = val() MILES = val() or this: class relationship(Enum): PARENT, SIBLING, CHILD = range(3) I'd probably wouldn't bother. I'd stick to "poor man's enum", like this: PARENT, SIBLING, CHILD = range(3) or (to my shame, but I have to be realistic) magic constants. -- Steven