Search code examples
pythonpython-3.xenumsenumeration

Get next enumerator constant/property


Lets's say I have an enumerator, is it possible to get the property that follows? So if I had today=Days.Sunday would I be able to do something like tomorrow=today.next()?

example:

class Days(Enum):
     Sunday = 'S'
     Monday = 'M'
     ...
     Saturday = 'Sa'

I know I could use tuples (like below) to do something like tomorrow=today[1], but I was hoping there was something built in or more elegant.

class Days(Enum):
     Sunday = ('S','Monday')
     Monday = ('M','Tuesday')
     ...
     Saturday = ('Sa','Sunday')

Solution

  • Absolutely.

    Just add the desired functionality to your Days class:

    class Days(Enum):
    
        Sunday = 'S'
        Monday = 'M'
        Tuesday = 'T'
        Wednesday = 'W'
        Thursday = 'Th'
        Friday = 'F'
        Saturday = 'Sa'
    
        def next(self):
            cls = self.__class__
            members = list(cls)
            index = members.index(self) + 1
            if index >= len(members):
                index = 0
            return members[index]
    

    and in use:

    today = Days.Wednesday
    print(today.next())
    # Days.Thursday
    

    While the above is probably easier to understand, it is possible to do the work once in __init__ by adding a next attribute to each member (and previous while we're at it).

    class Days(Enum):
        #
        Sunday = 'S'
        Monday = 'M'
        Tuesday = 'T'
        Wednesday = 'W'
        Thursday = 'Th'
        Friday = 'F'
        Saturday = 'Sa'
        #
        def __init__(self, value):
            if len(self.__class__):
                # make links
                all = list(self.__class__)
                first, previous = all[0], all[-1]
                previous.next = self
                self.previous = previous
                self.next = first
    

    and in use:

    >>> Days.Tuesday.next
    <Days.Wednesday: 'W'>
    
    >>> Days.Tuesday.previous
    <Days.Monday: 'M'>
    
    >>> Days.Saturday.next
    <Days.Sunday: 'S'>
    
    >>> Days.Saturday.previous
    <Days.Friday: 'F'>
    

    NB Using the this method of attributes means we no longer need the ()s after next/previous.