获取下一个枚举器常量/属性

问题描述 投票:0回答:5

假设我有一个枚举器,是否可以获得后面的属性?所以如果我有

today=Days.Sunday
我能做类似
tomorrow=today.next()
的事情吗?

示例:

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

我知道我可以使用元组(如下所示)来做类似

tomorrow=today[1]
的事情,但我希望有一些内置的或更优雅的东西。

class Days(Enum):
     Sunday = ('S','Monday')
     Monday = ('M','Tuesday')
     ...
     Saturday = ('Sa','Sunday')
python python-3.x enums enumeration
5个回答
10
投票

当然。

只需将所需的功能添加到您的

Days
类中即可:

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]

使用中:

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

虽然上面的内容可能更容易理解,但可以通过向每个成员添加

__init__
属性(以及我们使用时的
next
)来完成一次
previous
的工作。

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

使用中:

>>> 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 使用这种属性方法意味着我们不再需要

()
/
next
之后的
previous


2
投票

您可以创建一个字典来查找第二天,如下所示:

In [10]: class Days(Enum):
    Sun = 'Su'
    Mon = 'M'
    Tue = 'Tu'
    Wed = 'W'
    Thu = 'Th'
    Fri = 'F'
    Sat = 'Sa'

In [11]: days = list(Days)

In [12]: nxt = dict((day, days[(i+1) % len(days)]) for i, day in enumerate(days))

快速测试:

In [13]: nxt[Days.Tue]
Out[13]: <Days.Wed: 'W'>

In [14]: nxt[Days.Sat]
Out[14]: <Days.Sun: 'Su'>

0
投票
#ENUM CLASS

#colors
import enum

class Color(enum.Enum):
    turquoise = 1
    indigo = 2
    magenta = 3
    cyan = 4
    teal = 5
    azure = 6
    rose = 7
    amber = 8
    vermillon = 9
    plum = 10
    russet = 11
    slate = 12

    def __iter__(self):
        self.idx_current = self.value
        return self

    def __next__(self):
        if (self.idx_current > 12):
            return None

        self.idx_current = self.idx_current + 1
        return Color (self.idx_current - 1)

#CLIENT CODE
    #iterate colors starting from cyan
    it = iter (Color.cyan)
    while True:
        #print (v.get_id())
        c = next (it)
        if c is None:
            break
        print(c)

#OUTPUT
Color.cyan
Color.teal
Color.azure
Color.rose
Color.amber
Color.vermillon
Color.plum
Color.russet
Color.slate

0
投票

对我来说,这似乎是最优雅的解决方案,无需附加功能

day = Days.Sunday

day = Days((day.value + 1) % len(Days) + 1) # next day cycled

0
投票

所有提供的答案都会创建所有 Enum 成员的

list
,但实际上您可以通过使用
itertools.cycle
:

来避免它
from itertools import cycle

class Days(Enum):
    MONDAY = 'Mo'
    TUESDAY = 'Tu'
    WEDNSDAY = 'We'
    ...
    SATURDAY = 'Sa'
    
    def next(self):
        iterator = cycle(self)
        for member in iterator:
             if member is self:
                 # We have found the current member, so we want to return the next member
                 return next(iterator)

# Call it:
tomorrow = DAY.SUNDAY.next()

请注意,在这种方法中,如果当前成员是枚举中的最后一个成员,那么它将返回第一个成员,因为

cycle()
会永远循环您的可迭代对象。

使用

functools.cached_property
装饰器,我们还可以轻松保存结果以供进一步重用:

    @chached_property
    def next(self):
        # The rest of the code is the same.

# Call it:
tomorrow = DAY.SUNDAY.next  # Without parenthesis

要获取相同风格的前一个成员,您可以使用

reverse()
生成器:

    @cached_property
    def prev(self):
        # The only change is in the following line: we cycling in the revert order.        
        iterator = cycle(reverse(self))  
        for member in iterator:
             if member is self:
                 # We have found the current member, so we want to return the next member
                 return next(iterator)
© www.soinside.com 2019 - 2024. All rights reserved.