Thursday, October 24, 2013

Enums come to Python, finally!

In the newly released python 3.4, although no new syntax has been added, the enum library module is a new addition amongst other changes. this library brings the enum type as a first class construct (PEP 435). Although it was discussed in 2005, but was rejected back then. However, this year various discussions occurred on this topic and it was decided to let the enums be a subclass of int and act as integer placeholders.
Since the syntax of the language has not changed, the enum is not a special keyword per se, rather you need to add an import line declaring the use of enums in your script
from enum import Enum
Thereafter, any enumeration 'class' can be created. Note that it is preferable to call this as enumeration rather than a class (and enumeration members instead of objects) for the obvious reasons.

class Avengers(Enum):
  captain_america =1
  iron_man = 2
  hulk = 5
  thor = 3
If you prefer to go functional, then this is the format:
Avengers = Enum('Avengers', 'captain_america, iron_man, hulk, thor')

Whatever the case, you are free to subsitute these placeholders in place of integers like other languages that support enums.
print(Avengers.hulk)
type(Avengers.hulk)

The iteration is performed in the order of enum member definition, not their values.
for avenger in Avengers:
  print(avenger)

results in captain_america, iron_man, hulk and thor being printed out.
At times, you will not have an idea of the enum members during runtime. For this, the values can be used which allow access to those members (which is quite different from enums in other languages as per my experience)
heavy = Avengers(5)

Members and Attributes

As the enumerations are python classes in its core, they also support use of various custom members:

class Avengers(Enum):
  captain_america =1
  iron_man = 2
  hulk = 5
  thor = 3
  def inform(self):
    return '{0} coming in {1} second'.format(self.name, self.value)
  @classmethod
  def tagline():
    return 'Avengers unite!'

...
Avengers.tagline()
Avengers.hulk.inform()

Duplicacy

Having enums with same names is invalid, but two enum members can have same values (as the second member will be an alias to the first). While iterating, the alias will be skipped.

Comparisons

The equality and identity comparisons are allowed:
>>> Avengers.hulk is not Avengers.thor
true
>>> Avengers.thor == Avengers.iron_man
false
The comparisons with values will evaluate to false. If you wish to do that, use IntEnum which can compare its members with integers and other IntEnum subclasses, but Not with enum.

Happy Enum-ing !

No comments: