我可以创建一个枚举类RockPaperScissors
使得ROCK.value == "rock"
和ROCK.beats == SCISSORS
,其中ROCK
和SCISSORS
都是RockPaperScissors
中的常量吗?
答案 0 :(得分:8)
枚举成员是该类型的 instances 。这表示 您可以只使用常规属性:
checkPropagation: 'both'
答案 1 :(得分:2)
通过仔细选择成员的顺序,每个成员可以简单地描述为以property
击败前一个成员。
from enum import Enum
class RPS(Enum):
Rock = 0
Paper = 1
Scissor = 2
@property
def beats(self):
return list(RPS)[self.value - 1]
for v in RPS:
print(v.name, 'beats', v.beats.name)
Rock beats Scissor
Paper beats Rock
Scissor beats Paper
答案 2 :(得分:2)
在类创建期间让Enum
个成员相互引用有点棘手;诀窍是要知道在将每个成员添加到Enum
本身之前已创建并初始化了每个成员。这意味着您可以检查正在创建的Enum
的状态,并对正在创建的成员和已经创建的成员进行调整。
这里的基本问题是在成员之间进行循环引用,我们可以通过用每个新成员修改圆来解决该问题:
class RPS(Enum):
Rock = "rock"
Paper = "paper"
Scissors = "scissors"
def __init__(self, value):
if len(self.__class__):
# make links
all = list(self.__class__)
first, previous = all[0], all[-1]
first.beats = self
self.beats = previous
并在使用中:
>>> print(RPS.Rock.beats)
RPS.Scissors
>>> print(RPS.Paper.beats)
RPS.Rock
>>> print(RPS.Scissors.beats)
RPS.Paper
披露:我是Python stdlib Enum
,enum34
backport和Advanced Enumeration (aenum
)库的作者。
答案 3 :(得分:0)
您尝试了吗?
from enum import IntEnum
class RPS(IntEnum):
Rock = 1
Paper = 2
Scissor = 3
RPS.Rock.beats = RPS.Scissor
RPS.Paper.beats = RPS.Rock
RPS.Scissor.beats = RPS.Paper
for i in [RPS.Rock,RPS.Paper,RPS.Scissor]:
print(i, "beats", i.beats)
输出:
RPS.Rock beats RPS.Scissor
RPS.Paper beats RPS.Rock
RPS.Scissor beats RPS.Paper
是的。您可以。
在python中,所有(*)都是对象,您可以在其上附加更多属性:
def func():
pass
func.result = 42
print(func.result) # 42
*)少数例外情况适用
答案 4 :(得分:0)
那这样的事情呢?
from enum import IntEnum
class RPS(IntEnum):
Rock = 1,
Paper = 2,
Scissor = 3
def __lt__(self, other):
if self == RPS.Scissor and other == RPS.Rock:
return True
if self == RPS.Rock and other == RPS.Scissor:
return False
return self.value < other.value
def __gt__(self, other):
if self == RPS.Rock and other == RPS.Scissor:
return True
if self == RPS.Scissor and other == RPS.Rock:
return False
return self.value > other.value
这不是Rock.beats,但对于谁击败枚举(或类)谁似乎更合乎逻辑,它不是Rock击败Scissor的继承属性,这是我们定义RPS的方式(可以具有如果您决定尝试其他方法,也可以采取其他方法) 并使用python方法 ge (并且您可以根据需要实施其余操作),您可以自然地得到如下所示的比较:
from itertools import combinations
members = list(RPS)
for pair in combinations(members, 2):
print(f'{pair[1].name} < {pair[0].name} ? {pair[1] < pair[0]}')
print(f'{pair[0].name} < {pair[1].name} ? {pair[0] < pair[1]}')
print(f'{pair[1].name} > {pair[0].name} ? {pair[1] > pair[0]}')
print(f'{pair[0].name} > {pair[1].name} ? {pair[0] > pair[1]}')
输出:
Paper < Rock ? False
Rock < Paper ? True
Paper > Rock ? True
Rock > Paper ? False
Scissor < Rock ? True
Rock < Scissor ? False
Scissor > Rock ? False
Rock > Scissor ? True
Scissor < Paper ? False
Paper < Scissor ? True
Scissor > Paper ? True
Paper > Scissor ? False
答案 5 :(得分:0)
出于完整性考虑,也可以这样做。它更具描述性,但需要此getattr
调用,就我个人而言,我并不是最大的粉丝。
from enum import Enum
class RockPaperScissors(Enum):
ROCK = ("rock", "scissors")
PAPER = ("paper", "rock")
SCISSORS = ("scissors", "paper")
def __init__(self, value, beats):
self._value_ = value
self._beats = beats
@property
def beats(self):
return getattr(RockPaperScissors, self._beats.upper())