python tuple and enum
Asked Answered
H

5

14

So I was trying to use enums in python and came upon the following error: When I was using enum as a tuple and giving it two values, I can't access only one value such as tuple[0]

class Rank(Enum):
    ACE = 1
    TWO = 2
    THREE = 3
    FOUR = 4
    FIVE = 5
    SIX = 6
    SEVEN = 7
    EIGHT = 8
    NINE = 9
    TEN = 10
    JACK = 11
    QUEEN = 12
    KING = 13, "King"

print (Rank.KING.value)

and the print is

(13, 'King')

How can I access only one value so I can print 13 or 'King'?

Haemorrhage answered 20/2, 2019 at 18:30 Comment(0)
G
13

You have the following possibilites to access 13 or "king":

Rank.KING.value[0]
Rank.KING.value[1]
Globule answered 20/2, 2019 at 19:20 Comment(0)
E
17

With enum.Enum, the class variable names themselves become the name attribute of the enumerated attributes of the Enum instance, so you don't have to make KING a tuple of value and name:

class Rank(Enum):
    King = 13

print(Rank.King.name) # outputs 'King'
print(Rank.King.value) # outputs 13

If you want to name the class variables with capital letters but have their name values to be mixed-cased, which isn't what Enum is designed for, you would have to subclass Enum and override the name method yourself to customize the behavior:

from enum import Enum
from types import DynamicClassAttribute

class MixedCaseEnum(Enum):
    @DynamicClassAttribute
    def name(self):
        return self._name_.title()

class Rank(MixedCaseEnum):
    KING = 13

print(Rank.KING.name) # outputs 'King'
print(Rank.KING.value) # outputs 13
Emlynne answered 20/2, 2019 at 18:35 Comment(0)
G
13

You have the following possibilites to access 13 or "king":

Rank.KING.value[0]
Rank.KING.value[1]
Globule answered 20/2, 2019 at 19:20 Comment(0)
Q
11

None of the existing answers explained how you might have three (or more) values in an Enum, if you wanted to.

For example, say the initial questioner wanted (13, "K", "king") in the Enum, they would do it like this:


class Rank(Enum):
    K = 13, "King"

    def __init__(self, rank, label):
        self.rank = rank
        self.label = label

The __init__ takes the values and assigns them to the enum members. This means that Rank.K.rank returns 13 and Rank.K.label returns "King".

Although it's not strictly needed in this example, it can be useful to store more than key/value pairs on the Enum.

Note that Rank.K.value still exists, and returns the tuple (13, "King")

Queenie answered 12/12, 2021 at 15:41 Comment(1)
Thanks for this answer. One thing I realized is that you cannot define a member name, because it would conflict with Enum.name. The same way that Rank.K.value still exists, Rank.K.name does too.Cackle
C
2

You can just use indexes as you would use them on an array:

>>> KING = 13, 'King'
>>> KING
(13, 'King')
>>> KING[0]
13
>>> KING[1]
'King'
>>> 
Caracole answered 20/2, 2019 at 18:38 Comment(0)
W
0

If you wanna preserve .value initial funcionality, you can use Enum.__new__().

class Rank(int, Enum):
    QUEEN = 12
    KING = 13, 'King'

    def __new__(cls, value, label='...'):
        obj = int.__new__(cls, value)
        obj._value_ = value
        obj.label = label
        return obj

print(Rank.QUEEN.label)
print(Rank.KING.label)

Docs: https://docs.python.org/3/howto/enum.html#when-to-use-new-vs-init

Wilbanks answered 9/2, 2023 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.