32

One advantage of enums in Java and other languages is that I do not have to care about specific values (in contrast to constants/static final members). For example, in Java I can do the following:

public enum Color {
    RED, BLUE;
}

At least to my knowledge, in python I have to do the following:

class Color(Enum) {
    RED = "red" # or e.g 1
    BLUE = "blue" # or e.g. 2
}

If I have an enum with hundreds of names, then this can get quite cumbersome, because I always have to keep track whether a value was already assigned to a name or not. Is it maybe possible to achieve the same result as in Java without resorting to generators or the like?

1

3 Answers 3

40

If you're using Python 3.6 or later, you can use enum.auto():

from enum import Enum, auto

class Color(Enum):
    RED = auto()
    BLUE = auto()

The documentation for the enum library describes this and other useful features like the @unique decorator.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, it can auto-count. Did they use AI for it?
31

One way is to use the Enum base class as a callable:

Color = Enum('Color', 'RED BLUE GREEN ORANGE')

4 Comments

Is there a downside to this method?
Why would you expect downsides? This method is officially explained in the documentation that you linked, so it should be as good as the class syntax.
With this method you are not stuck with '=' which is closer to what is asked by the questions. I am also glad to see that Intellisence (pylance) manage to make a link between the Enum and the values
Well there is a small downside, Intellisence (pylance) does work but you need to dig your param in the available options. With the @Greg Hewgill option, you don't have this issue but you are stuck again with '= ...'
8

The answer from Daniel Roseman is an elegant solution, that is in line with the official documentation and that should be appropriate in most cases.

Only for completeness here are a few other options.

class Color(Enum):
    RED, BLUE = range(2)

This will even work without the enum package.

class Color:
    RED, BLUE = range(2)

But this solution has some drawbacks. For example if you print Color.RED, you don't see the name, but the number.

In principle an enum is just a list of constants. So even the following works if you completely define it without a surrounding class.

RED, BLUE = range(2)

I don't want to discuss the advantages and disadvantages of this. There may be specific uses cases of such code.

Note: It must be said here, that range(2) starts counting at 0. So the first value, when used as a boolean expression is evaluated to False. This is normally not, what someone wants. It could be a nice feature in very specific situations (if your first value is intentionally something like INVALID or UNDEFINED). But normally it should be better to use range(1,3) instead of range(2).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.