27

I want to use enums in python like in code below (java). I am a greenhorn in Python. I have the following code in Java and want to replicate the functionality in Python:

class Direction {
  public enum Direction {LEFT, RIGHT, UP, DOWN}

  public void navigate(Direction direction)
    switch(direction){
        case Direction.LEFT:
            System.out.print("left");
            break;
        case Direction.RIGHT:
            System.out.print("right");
            break;
        case Direction.UP:
            System.out.print("up");
            break;
        case Direction.DOWN:
            System.out.print("down");
            break;
  }
}

How can I enforce users to only provide an enum to a Python method?

Alastair McCormack
  • 26,573
  • 8
  • 77
  • 100
user2678074
  • 768
  • 3
  • 9
  • 22
  • 6
    Possible duplicate of [How can I represent an 'Enum' in Python?](http://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python) – Alastair McCormack Feb 15 '16 at 10:58
  • 1
    I saw that one, but it doesn't explain (at least to me), how to pass enum element as parameter and force user to use enum elements instead of typing raw strings or different values. – user2678074 Feb 15 '16 at 12:21
  • 1
    I've updated the question with that as the thrust of your question. Ideally you would've provided Python code so we could see what you were trying to achieve – Alastair McCormack Feb 15 '16 at 12:41

2 Answers2

28

Python is dynamic and duck typed - variables can change type and you can't force types on methods.

You can, however, check for types in the body of a method using isinstance().

isinstance() will allow users to subclass your enum for future extensibility. - See comments

E.g.

# Python 2.x: pip install enum34
from enum import Enum

class Direction(Enum):
    LEFT = "left"
    RIGHT = "right"
    UP = "up"
    DOWN = "down"

def move(direction):

    # Type checking
    if not isinstance(direction, Direction):
        raise TypeError('direction must be an instance of Direction Enum')

    print direction.value

>>> move(Direction.LEFT)
left
>>> move("right")
TypeError: direction must be an instance of Direction Enum
Alastair McCormack
  • 26,573
  • 8
  • 77
  • 100
14

The "pythonic" thing to do is to follow the principle of duck-typing: Try to accept the value you are passed without making too big of a fuss. In this case, instead of enforcing the type I would simply check for equality with each enum value, and raise an error for anything that cannot be handled:

def navigate(direction):
    """Turn toward `direction` (an enum of type `Direction`)"""

    if direction == Direction.left:
         print("Left")
    elif direction == Direction.right:
         (etc., etc.)
    else:
         # Hmm, `direction` does not compare equal to any enum value:
         raise ValueError("Invalid direction "+ str(direction))
alexis
  • 48,685
  • 16
  • 101
  • 161
  • 5
    I got this and now I'm so thankful for all the coding gods for languages with object types. Thank you all for help though. – user2678074 Mar 10 '16 at 14:59