user2678074
user2678074

Reputation: 825

Enums in Python: How to enforce in method arguments

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?

Upvotes: 31

Views: 62534

Answers (2)

Alastair McCormack
Alastair McCormack

Reputation: 27744

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

Upvotes: 33

alexis
alexis

Reputation: 50220

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))

Upvotes: 17

Related Questions