python: how to convert if statements to enum or make it pythonic

  • Last Update :
  • Techknowledgy :

Use a dict of key, values. Where key is the incoming state, and the value is the outgoing state. This is a highly Pythonic pattern and one you will likely reuse again and again. In many cases you will want to dispatch on the input state, where you should put functions as values in the dict.

recs = {
   'SELL': 1,
   'UNDERWEIGHT': 2,
   'HOLD': 3,
   'OVERWEIGHT': 4,
   'BUY': 5,
}

# this will fail correctly with a KeyError
for non - expected states.
recommendation = recs[avg_recommendation]

With enum34:

>>> import enum
>>> class Recommendation(enum.IntEnum):
... BUY = 5
... OVERWEIGHT = 4
... HOLD = 3
... UNDERWEIGHT = 2
... SELL = 1
>>> Recommendation.BUY
<Recommendation.BUY: 5>
   >>> Recommendation.BUY.value
   5
   >>> Recommendation(5)
   <Recommendation.BUY: 5>
      >>> recs = [Recommendation.BUY, Recommendation.HOLD, Recommendation.BUY]
      >>> avg_rec = sum(recs)//len(rec)
      >>> Recommendation(rec)
      <Recommendation.OVERWEIGHT: 4>

Meanwhile, what if you have a string, like 'HOLD', and you want to get a Recommendation.HOLD out of that? Unfortunately, that's one of the features that was intentionally left out of the stdlib enum module to keep it simple.* (Read PEP 435 for a full discussion of all of the possible features that were left out and why.) So, if you try it, you'll get an error:

>>> Recommendation('HOLD')
ValueError: HOLD is not a valid Recommendation

But you could use one of the many other enum modules on PyPI. In particular, flufl.enum** works exactly like the stdlib in all the examples shown above, but also has a few extra features. So, if you pip install flufl.enum, then change the import enum to from flufl import enum, all of the above will work, and so will this:

>>> Recommendation('HOLD')
<EnumValue: Recommendation.HOLD [value=3]>

Suggestion : 2

Functional Programming HOWTO,Enum classes with methods

>>> from enum
import Enum
   >>>
   class Weekday(Enum):
   ...MONDAY = 1
   ...TUESDAY = 2
   ...WEDNESDAY = 3
   ...THURSDAY = 4
   ...FRIDAY = 5
   ...SATURDAY = 6
   ...SUNDAY = 7
>>> from enum
import Enum
   >>>
   class Color(Enum):
   ...RED = 1
   ...GREEN = 2
   ...BLUE = 3
>>> Weekday(3)
<Weekday.WEDNESDAY: 3>
>>> print(Weekday.THURSDAY)
Weekday.THURSDAY
>>> type(Weekday.MONDAY)
<enum 'Weekday'>
   >>> isinstance(Weekday.FRIDAY, Weekday)
   True
>>> print(Weekday.TUESDAY.name)
TUESDAY

Suggestion : 3

Last Updated : 16 Aug, 2022

Output: 

Season.SPRING
SPRING
1
<enum 'Season'>
   <Season.SPRING: 1>
      [<Season.SPRING: 1>, <Season.SUMMER: 2>, <Season.AUTUMN: 3>, <Season.WINTER: 4>]

Output:

Enum is hashed

Suggestion : 4

last modified August 5, 2022

1._
#!/usr/bin/python

from enum
import Enum

class Season(Enum):
   SPRING = 1
SUMMER = 2
AUTUMN = 3
WINTER = 4

seas = Season.SPRING
print(seas)

if seas == Season.SPRING:
   print("Spring")

print(list(Season))

In the example, we have a Season enumeration which has four distinct values: SPRING, SUMMER, AUTUMN, and WINTER. To access a member, we specify the enumeration name followed by a dot and the member name.

class Season(Enum):
   SPRING = 1
SUMMER = 2
AUTUMN = 3
WINTER = 4

The Season enumeration is created with the class keyword. We inherit from the enum.Enum base class. We explicity set numbers to the enumeration values.

seas = Season.SPRING
print(seas)

The Season.SPRING is used in an if expression.

print(list(Season))

With the list built-in function, we get the list of all possible values for the Season enum.

$ ./simple.py
Season.SPRING
Spring
[<Season.SPRING: 1>, <Season.SUMMER: 2>, <Season.AUTUMN: 3>, <Season.WINTER: 4>]

Suggestion : 5

In this article, you will learn what enums are and how to create and work with them. Furthermore, you will learn why you should use them more often in your day to day coding.,At this point, we have an understanding of what enums are and how we can create them in Python. Furthermore, we are able to compare and work with them. However, we still do not know why we need and should use enumerations more often.,In essence, if you have magic numbers in your code, you should definitely consider to either assign them to a variable or group them together to an enumeration. This way your code's readability increases a lot. It is especially true if you want to write tests for your code.,Note: Although the class syntax is used to define new enumerations, they aren't normal Python classes. If you want to know more about it, check out the How are Enums different? section in the module's documentation [1]:

The following code snippet shows you a simple example of an enum Colour:

# colour.py

from enum
import Enum

class Colour(Enum):
   RED = 1
GREEN = 2
BLUE = 3

Let's see how enums behave when used.

# previous colour.py code

c = Colour.RED
print(c)
print(c.name)
print(c.value)
print(c is Colour.RED)
print(c is Colour.BLUE)

We extended the colour.py script by creating a new instance of Colour.RED and assigning it to the variable c. Furthermore, we print the string representation of Colour.RED, its name and value. Additionally, we compare c's identity with Colour.RED and Colour.BLUE.

$ python colour.py
Colour.RED
RED
1
True
False
# iterate.py

from enum import Enum


class Colour(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3


for name, member in Colour.__members__.items():
    print(name, member)
$ python iterate.py
RED Colour.RED
GREEN Colour.GREEN
BLUE Colour.BLUE

You might ask yourself why we did not something like:

for member in Colour:
   print(member.name, member)

Enumerations have a special attribute called __members__, which is a read-only ordered mapping of names and members. Utilising __members__ allows you to iterate over an enum and print the members as well as their corresponding names.

# iterate.py

from enum
import Enum

class Colour(Enum):
   RED = 1
GREEN = 2
BLUE = 3

for name, member in Colour.__members__.items():
   print(name, member)
# iterate.py

from enum import Enum


class Colour(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3


for name, member in Colour.__members__.items():
    print(name, member)
$ python iterate.py
RED Colour.RED
GREEN Colour.GREEN
BLUE Colour.BLUE

You might ask yourself why we did not something like:

for member in Colour:
   print(member.name, member)

In the previous example, we assigned integers to the symbolic names RED, GREEN, and BLUE. If the exact values are not important, you can use the enum.auto() function. The function calls _generate_next_value_() internally and generates the values for you.

# auto.py

from enum
import auto
from enum
import Enum

class Colour(Enum):
   RED = auto()
GREEN = auto()
BLUE = auto()

c = Colour.RED
print(c.value)

It chooses a suited value for each enum member, which will (most of the time) be the integers we used before.

$ python auto.py
1
$ python overwritte_next_values.py
2
4
8

Being Python classes, enums can have any (special) methods just like all other classes. Consider the following example.

# extending.py

from enum
import Enum

class Colour(Enum):
   RED = 1
GREEN = 2
BLUE = 3

def __str__(self):
   return self.name

def colorize(self):
   return f "Let's paint everything in {self.name.lower()}"

c = Colour.RED
print(c)
print(c.colorize())

We extended the Colour enum by a new method colorize() printing a string generated based on the member's value. Furthermore, we overwrite the __str__() dunder method to return the member's name if called.

$ python extending.py
RED
Let 's paint everything in red

We already know that we can compare enum members using Python's identity operator. However, the Enum class does not provide ordered comparisons even though integers are used as values for the enumeration members. Let's have a look at the following example.

# comparison.py

from enum
import Enum

class Colour(Enum):
   RED = 1
GREEN = 2
BLUE = 3

r = Colour.RED
b = Colour.GREEN
print(r < b)

Executing the script at hand results in a TypeError.

$ python comparison.py
Traceback (most recent call last):
File "/home/florian/workspace/python/why-you-should-use-more-enums-in-python-article-snippets/comparison.py", line 14, in <module>
   print(r < b) TypeError: '<' not supported between instances of 'Colour' and 'Colour'

However, the derived enumeration IntEnum does provide ordered comparisons as it is also a subclass of int. In order to make our example work, we need to import the IntEnum class instead of Enum and derive Colour from it. We do not need to change anything else.

# comparison.py

from enum
import IntEnum

class Colour(IntEnum):
   ...

If we have a user, who should have read and write permissions for a certain file, we can combine both using the | operator.

# permissions.py

from enum
import IntFlag

class Permission(IntFlag):
   R = 4
W = 2
X = 1

RW = Permission.R | Permission.W
print(RW)
print(Permission.R + Permission.W)
print(Permission.R in RW)
$ python permissions.py
Permissions.R | W
6
True

Suggestion : 6

Python is the main dynamic language used at Google. This style guide is a list of dos and don’ts for Python programs.,Never use spaces around = when passing keyword arguments or defining a default parameter value, with one exception: when a type annotation is present, do use spaces around the = for the default parameter value.,Default arguments are evaluated once at module load time. This may cause problems if the argument is a mutable object such as a list or a dictionary. If the function modifies the object (e.g., by appending an item to a list), the default value is modified.,Simpler code, because the state of local variables and control flow are preserved for each call. A generator uses less memory than a function that creates an entire list of values at once.

dict = 'something awful'
# Bad Idea...pylint: disable = redefined - builtin
pylint--list - msgs
pylint--help - msg = C6409
def viking_cafe_order(spam: str, beans: str, eggs: Optional[str] = None) - > str:
   del beans, eggs # Unused by vikings.
return spam + spam + spam
from sound.effects
import echo
   ...
   echo.EchoFilter(input, output, delay = 0.7, atten = 4)
Yes:
   # Reference absl.flags in code with the complete name(verbose).
import absl.flags
from doctor.who
import jodie

_FOO = absl.flags.DEFINE_string(...)

Suggestion : 7

I know I can hand craft a series of if-statements to do the conversion but is there an easy pythonic way to convert? Basically, I'd like a function ConvertIntToFruit(int) that returns an enum value.,From the Programmatic access to enumeration members and their attributes section of the documentation:,Given the following definition, how can I convert an int to the corresponding Enum value?,My use case is I have a csv file of records where I'm reading each record into an object. One of the file fields is an integer field that represents an enumeration. As I'm populating the object I'd like to convert that integer field from the file into the corresponding Enum value in the object.

Given the following definition, how can I convert an int to the corresponding Enum value?

from enum
import Enum

class Fruit(Enum):
   Apple = 4
Orange = 5
Pear = 6

You 'call' the Enum class:

Fruit(5)

to turn 5 into Fruit.Orange:

>>> from enum import Enum
>>> class Fruit(Enum):
... Apple = 4
... Orange = 5
... Pear = 6
...
>>> Fruit(5)
<Fruit.Orange: 5>

Sometimes it’s useful to access members in enumerations programmatically (i.e. situations where Color.red won’t do because the exact color is not known at program-writing time). Enum allows such access:

>>> Color(1)
<Color.red: 1>
   >>> Color(3)
   <Color.blue: 3>

Sometimes it’s useful to access members in enumerations programmatically (i.e. situations where Color.red won’t do because the exact color is not known at program-writing time). Enum allows such access:

>>> Color(1)
<Color.red: 1>
   >>> Color(3)
   <Color.blue: 3>