with lukas.brain: python = 42
enumeration) defines a set of named values.
enum name { value1, value2, value3 }
var
(implicitly, parenthesised list)TYPE name = {value1, value2, value3 };
MODE name = dtype; MODE value1 = value1, …
C/C++:
enum fruits { apple, banana, cherry };
enum fruits { apple = 0, banana = 1, cherry = 2 };
Java:
enum Fruits { APPLE(0), BANANA(1), CHERRY(2); private int value; Fruits(int value) { this.value = value; } public int value() { return value; } }
enum Fruits { APPLE, BANANA, CHERRY };
const ( apple = iota banana cherry )
object Fruit extends Enumeration { val Apple, Banana, Cherry = Value } sealed abstract class Fruit case object Apple extends Fruit case object Banana extends Fruit case object Cherry extends Fruit
(def fruits #{:apple :banana :cherry}) (defn fruit? [x] (contains? fruits x)) (def fruit-value (zipmap fruits (iterate inc 1))) (println (fruit? :apple)) (println (fruit-value :banana))
data Fruit = Apple | Banana | Cherry deriving Enum
So we have it in programming languages!
And how/when to use them?
Set of possible values [only useful if no other values can be assigned to value of this enum type].
enum DateConfig { ISO8601, RFC5322 } enum Permissions { READ, WRITE, EXEC } enum Grades { A, B, C, D, F }
Be aware that it's probably better to keep the values binary disjunct
(Name.Value1 & Name.Value2 = 0
)
[depending on whether or not you want to apply binary operators].
So the Permissions
values are actually { READ = 0, WRITE = 1, EXEC = 2 }
whereas they are { READ = 4, WRITE = 2, EXEC = 1 }
on UNIX.
Compare this with the {True,False}-discussion in python.
Type–token distinction.
One state triggers certain component. Result of component defines which state to enter next (or unconditionally).
state = INIT requests = 42 while True: if state == INIT: initialize() state = READY elif state == READY if requests == 0: state = SHUTDOWN continue success = handle_request() if success: state = READY else: state = ERROR requests -= 1 elif state == ERROR: logging.error("Error occured while handling request") state = SHUTDOWN elif state == SHUTDOWN: teardown()
So, what about python?
This doesn't slot nicely into any of the existing modules (like collections), and the Python standard library eschews having lots of individual data structures in their own modules. Also, the PEP has generated no widespread interest. For those who need enumerations, there are cookbook recipes and PyPI packages that meet these needs.
Let's just import Barry's enums into the stdlib.(Feb 2012)
I have reviewed the latest version of PEP 435 and I see that it is very good. I hereby declare PEP 435 as Accepted. […] It is a better PEP because of the reviews.
Good mailinglist post summing up design ideas (by Michael Foord)
state2 > state1
?
[PEP 354 says, provide ordering, hide enumeration]type(Fruit.apple) == Fruit
Enum.value * 2
would be stupid.(Adapted to our rosettacode example and summarized).
iter(Fruit)
returns elements in definition order?
Yes, let's agree on that.
Fruit(val)
allowed? For example:
class Fruit(Enum): apple = 1 banana = 2 cherry = 3 x = Fruit.apple assert Fruit(x) is Fruit.apple assert Fruit(1) is Fruit.apple Fruit(42) # raises
Fruit('apple')
is Fruit.apple
. No, rejected.
getattr(Fruit, 'apple')
is possible anyway and
bool('False')
doesn't return False
anyway.
Let's not hypergeneralize and try to make bool and enums completely alike. [...] Type bool is its own thing, but that doesn't mean enums can't emulate aspects of it.
Using objects instead of numbers?
>>>> a = object() >>>> b = object() >>>> a == b False
… achieving uniqueness, no ordering.
Integers as enum value would mean comparisons between enums of unrelated types is misleading.
Using a class with class variables? So what is instantiation for? Inheritance is obviously extension. Mixins are uncommon for extension of homogeneous members.
>>> Weekdays = enum('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat')
>>> class Color(Enum): ... red = 1 ... green = 2 ... blue = 3
APPLE, BANANA, CHERRY = range(3) val = BANANA val == BANANA
Intuitive typing behavior
String representation
Add values at runtime
Hiding value index
Assigning indices automatically
Ordering
Group = make_constants('Group', name1=value1, name2=value2) name1, name2 = Group.name1, Group.name1 flag = name1 | name2
via Michael Foord
? Intuitive typing behavior
? String representation
Add values at runtime
Hiding value index
Assigning indices automatically
Ordering
>>> from enum import Enum >>> class Fruit(Enum): ... apple = 1 ... banana = 2 ... cherry = 3
Fruit is the enum.
apple is an enum member.
1 is the enum value.
>>> print(Fruit.apple) Fruit.apple >>> print(repr(Fruit.apple)) <Fruit.apple: 1>
>>> type(Fruit.apple) <Enum 'Fruit'> >>> isinstance(Fruit.apple, Fruit) True >>> print(Fruit.apple.name) apple
>>> class Fruit(Enum): ... apple = 42 ... banana = 3 ... cherry = 11 ... >>> for fruit in Fruit: ... print(fruit) ... Fruit.apple Fruit.banana Fruit.cherry
>>> plantation = {} >>> plantation[Fruit.apple] = 'Available in sector C' >>> plantation[Fruit.banana] = 'Not available in summer 2013' >>> plantation {<Fruit.apple: 1>: 'Available in sector C', <Fruit.banana: 2>: 'Not available in summer 2013'}
>>> class Fruit(Enum): ... apple = 1 ... apple = 2 ... Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in Fruit File "/usr/local/lib/python3.4/enum.py", line 88, in __setitem__ raise TypeError('Attempted to reuse key: %r' % key) TypeError: Attempted to reuse key: 'apple' >>> class Fruit(Enum): ... apple = 1 ... banana = 1 ... cherry = 2 ... >>> list(Fruit) [<Fruit.apple: 1>, <Fruit.cherry: 2>] >>>
>>> for name, member in Fruit.__members__.items(): ... name, member ... ('square', <Fruit.square: 2>) ('diamond', <Fruit.diamond: 1>) ('circle', <Fruit.circle: 3>) ('alias_for_square', <Fruit.square: 2>)
>>> Fruit.apple is Fruit.apple True >>> Fruit.apple is Fruit.cherry False >>> Fruit.apple is not Fruit.cherry True >>> Fruit.apple < Fruit.cherry Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: Fruit() < Fruit() >>> Fruit.cherry == Fruit.apple False >>> Fruit.cherry != Fruit.apple True >>> Fruit.cherry == Fruit.cherry True >>> Fruit.cherry == 2 False
>>> Animal = Enum('Animal', 'ant bee cat dog') >>> Animal <Enum 'Animal'> >>> Animal.ant <Animal.ant: 1> >>> Animal.ant.value 1 >>> list(Animal) [<Animal.ant: 1>, <Animal.bee: 2>, <Animal.cat: 3>, <Animal.dog: 4>]
IntEnum
class
PEP 435 contains many API examples.
Python 3.4 ships the enum package.
Intuitive typing behavior
String representation
Add values at runtime
Hiding value index
Assigning indices automatically
Ordering
Have fun using it!