如何创建自引用的Python 3枚举?

l0b*_*0b0 12 python python-3.6

我可以创建一个枚举类RockPaperScissors,使ROCK.value == "rock"and ROCK.beats == SCISSORS,where ROCKSCISSORS均为常量RockPaperScissors吗?

wim*_*wim 19

枚举成员是该类型的实例。这意味着您可以只使用常规属性:

from enum import Enum

class RockPaperScissors(Enum):
    Rock = "rock"
    Paper = "paper"
    Scissors = "scissors"

    @property
    def beats(self):
        lookup = {
            RockPaperScissors.Rock: RockPaperScissors.Scissors,
            RockPaperScissors.Scissors: RockPaperScissors.Paper,
            RockPaperScissors.Paper: RockPaperScissors.Rock,
        }
        return lookup[self]
Run Code Online (Sandbox Code Playgroud)


Oli*_*çon 6

通过仔细挑选成员的顺序,每个成员都可以简单地描述为以 击败前一个成员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)
Run Code Online (Sandbox Code Playgroud)

输出

Rock beats Scissor
Paper beats Rock
Scissor beats Paper
Run Code Online (Sandbox Code Playgroud)


Eth*_*man 5

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
Run Code Online (Sandbox Code Playgroud)

并在使用中:

>>> print(RPS.Rock.beats)
RPS.Scissors

>>> print(RPS.Paper.beats)
RPS.Rock

>>> print(RPS.Scissors.beats)
RPS.Paper
Run Code Online (Sandbox Code Playgroud)

声明:我是Python stdlibEnumenum34backportAdvanced Enumeration ( aenum)库的作者 。