假设我有一个枚举器,是否可以获得后面的属性?所以如果我有
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')
当然。
只需将所需的功能添加到您的
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
。
您可以创建一个字典来查找第二天,如下所示:
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'>
#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
对我来说,这似乎是最优雅的解决方案,无需附加功能
day = Days.Sunday
day = Days((day.value + 1) % len(Days) + 1) # next day cycled
所有提供的答案都会创建所有 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)