Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a good use case for enums in python?

Tags:

python

enums

I've been writing Python 2 code for ~ 3 years now, and although I've known about enums for a long time, we've started using them in our project (backported - pypi package enum34 ).

I'd like to understand when to use them.

One place where we started using them was to map some postgres database level enums to python enums. Therefore we have this enum class

class Status(enum.Enum):
    active = 'active'
    inactive = 'inactive'

But then when using these, we've ended up using them like this:

if value == Status.active.value:
    ...

And so using enums in this case is less helpful than just using a more simple class, like this

class Status(object):
    active = 'active'
    inactive = 'inactive'

Because we could use this more easily, like value == Status.active.

So far the only place I found this useful - though not as useful as I'd like - is in docstrings. Instead of explicitly saying that allowed values are 'active' and 'inactive', I can just declare that my formal parameter takes expects a member of the Status enum (more helpful when more statuses exist)

So I don't really know what would be their exact use case - I don't know how they're better than string constants.

In short: when to use enums?

like image 956
vlad-ardelean Avatar asked Jan 18 '17 17:01

vlad-ardelean


3 Answers

I use Enum most often in GUI design. Imagine you have a radio button such asenter image description here

This represents a list of fixed choices, so under the hood, it's well represented by an Enum. That is, if a user picks button 2, then Enum.Choice.Choice2 could be returned by some callback. This is better than returning an int 2 or string "choice 2", as there's nothing to validate these later. In other words, if you changed "choice 2" to "user choice 2", you could potentially break downstream components expecting the original symbol.

Think of Enum as a convenient shortcut to presenting a static set of choices, rather than creating boilerplate object classes.

I've found Enum's in Java (and other statically typed languages I presume) to be a bit more useful, as you can declare them in a method signature. For example, a method may have the signature,

public void (Enum.Choice, mychoice)

Instead of

public void (String, mychoice)

In the second case, users may have to know ahead of time that mychoice should be "foo" or "bar", but what if they pass in "baz", which is invalid. Using an Enum will ensure invalid input can't be passed to the method, as Enum.Choice would only have fields foo and bar. You couldn't create a baz Choice if you tried.

Sorry, I strayed into Java. Is this too off topic to be helpful?

like image 82
Adam Hughes Avatar answered Oct 24 '22 04:10

Adam Hughes


A couple points:

  • Your Enum class can use str as a mixin.
  • Some database layers allow converting the stored data into Python data types.

For the first point:

class Status(str, Enum):
    active = 'active'
    inactive = 'inactive'

...

if value == Status.active:
    ...

For the second point:

I have little experience here, but I believe SQLAlchemy will do this.

like image 25
Ethan Furman Avatar answered Oct 24 '22 05:10

Ethan Furman


The issue you see is because your ORM isn't mapping database values to your Enum object. If it did, you wouldn't have to deal with .value.

An alternative would be something like:

if Status(value) is Status.active: since the constructor creates an Enum from the given argument.

like image 24
Josh J Avatar answered Oct 24 '22 05:10

Josh J