Mar 17, 2014

Enumeration in Python


What are Enums?

An enumerator(also called Enum) allows mapping a set of symbolic names(also known as elements or members) to a set of constant values. The symbolic names can be compared within an Enum. Enums can also be iterated over. They are used to define immutables. They may also be thought of as identifiers which behave as constants in that language.


Enums in other languages

Enums were added to C as a part of C89. They are defined similar to structs and unions. C++ directly inherits Enums from C, and works similarly. Java treats Enums as a special type of classs and provides utility methods.Perl is one of the few dynamically typed languages to provide Enums, albeit a hack - using string lists and hashes. 

Enums in Python

Python introducedEnum support in Python 3.4 . It was added as a part of PEP435. This addition subclasses the int class. This allows developers to replace unfriendly and difficult-to-maintain constants (integers) with user friendly and readable string representations. Because of the way it is implemented, it does NOT break backwards compatibility. 

Using Enums in Python

The following example is used throughout this blog post to explain all the features of Python's Enum. Enums creation follows class syntax - one creates a new class which inherits from Enum. In this example, the Day class inherits from the Enum class. The class "Day" is an Enum. Its attributes - sunday , monday ..... saturday are the Enum members. All enum members are associated with a name and value.The name of Day.tuesday is "tuesday" and its value is 3.
>>> from enum import Enum
>>> class Day(Enum):
sunday = 1
monday = 2
tuesday = 3
wednesday = 4
thursday = 5
friday = 6
saturday = 7

Printing an enum is as simple as passing it to print().It produces the output
>>>print(Day.tuesday)
Day.tuesday
This type of representation is not very helpful.To obtain the name-value relationship, we call repr() on the Enum member as follows

>>>print(repr(Day.tuesday))
'<Day.tuesday: 3>'

 The type() method works on Enums. It is used to obtain the name of the Enum.
>>>type(Day.tuesday)
<enum 'Day'>
A string (str) representation of the Enum member name can be obtained by:
>>>Day.tuesday.name
tuesday
The reverse is also possible i.e. given a Enum member name, it is possible to extract its value as shown below.
>>> Day.tuesday.value
3
As stated earlier in this post, Enum objects are iterable. The order of iteration is the order in which they were defined.
>>> for day in Day:
print(day)
Day.sunday
Day.monday
Day.tuesday
Day.wednesday
Day.thursday
Day.friday
Day.saturday
While you can access Enums as Day.tuesday, this method does have an obvious flaw - what if the Enum member names are not known at the time of writing code? The reverse method is also possible -
>>> print(Day(3))
Day.tuesday
 If you are familiar with how dict or JSON works, Enums also provide access in a similar way.An Enum member may be accessed as shown below.
>>> print(Day['tuesday'])
Day.tuesday
 Two Enum members may not have the same name. If you try to do so, a "TypeError" will be raised. However, Python permits two or more members to have the same value.
Another drawback is, though Enum members map to constant values, they cannot be compared. In this example, if you wanted to test whether Tuesday comes earlier than Monday, you may be tempted to use
if Day.tuesday < Day.monday,  but again, a TypeError will be raised.
>>> Day.tuesday < Day.monday
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    Day.tuesday < Day.monday
TypeError: unorderable types: Day() < Day()
Then again,equality comparision test works!!
>>> Day.monday == Day.tuesday
False
>>> Day.tuesday == Day.tuesday
True
The way Enums are designed in Python(and a host of other languages like Java, C#), don't allow the execution of nonsensical statements like
>>> Day.tuesday*42
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    Day.tuesday*42
TypeError: unsupported operand type(s) for *: 'Day' and 'int'

Use of Enum

Here I list out some generic and typical use cases of Enum

  • When you need to ensure that a variable can take only a small set of values. An example would be a variable to store the status of an order. It may only contain values [processing, cancelled, completed] and may require mapping to a more basic data structure like int.
  • It reduces the chances of mistakes due to mistyping numbers
  • It is easier to redefine values in code - Using Enum , you may change the value of a constant appearing throughout the program, by modifying the value only once.
  • Increases the readability of your code and thereby reduces the chance of errors creeping in.



Hello world!
I'd also like to take this opportunity to say Hi! to all of you. This is my first blog post. Looking forward to you reading my blog regularly. Looking forward to interact with all of you. Please do comment on this blog.
Saimadhav A Heblikar.


 





No comments:

Post a Comment