Réfrencer une autre énumération en tant que valeur enum en Python? [dupliquer]

Sep 18 2020

Supposons que j'ai un Enum Python où chaque instance de l'Enum devrait référencer une autre instance de la même énumération. Comment je fais ça?

Quand j'essaye quelque chose comme ça:

    class Direction(Enum):
        NORTH = (1,0, Direction.EAST, Direction.WEST)
        SOUTH = (-1,0, Direction.WEST, Direction.EAST)
        EAST = (0,1, Direction.SOUTH, Direction.NORTH)
        WEST = (0, -1, Direction.NORTH, Direction.SOUTH)
        
        def __init__(self, y, x, r, l):
            self.y = y
            self.x = x
            self.r = r
            self.l = l

J'obtiens une erreur qui ressemble un peu à ceci:

Traceback (most recent call last):
  File "lol.py", line 2, in <module>
    class Direction(Enum):
  File "lol.py", line 3, in Direction
    NORTH = (1,0, Direction.EAST, Direction.WEST)
NameError: name 'Direction' is not defined

J'obtiens le même problème lorsque je remplace "Direction" par "self" dans l'exemple ci-dessus.

Y a-t-il un moyen de faire cela?

Réponses

1 EthanFurman Sep 22 2020 at 05:24

Si cela ne vous dérange pas de réorganiser légèrement votre Enum, c'est assez simple:

class Directions(Enum):
    #
    NORTH = 1, 0
    EAST = 0, 1
    SOUTH = -1, 0
    WEST = 0, -1
    #
    def __init__(self, x, y):
        self.x = x
        self.y = y
        if len(self.__class__):
            # make links
            all = list(self.__class__)
            left, right = all[0], all[-1]
            self.left = left
            self.right = right
            left.right = self
            right.left = self

et en cours d'utilisation:

>>> Directions.NORTH
<Directions.NORTH: (1, 0)>

>>> Directions.NORTH.left
<Directions.EAST: (0, 1)>

>>> Directions.NORTH.right
<Directions.WEST: (0, -1)>

>>> Directions.WEST.left
<Directions.NORTH: (1, 0)>

>>> Directions.WEST.right
<Directions.SOUTH: (-1, 0)>

Divulgation: Je suis l'auteur de la bibliothèque Python stdlibEnum , du enum34backport et de la bibliothèque Advanced Enumeration ( aenum) .

Grismar Sep 18 2020 at 13:28

Vous pouvez utiliser la suggestion @antont et utiliser un dictionnaire, c'est parfaitement valable.

Une autre solution, proche de l'original:

from enum import Enum


class Direction(Enum):
    NORTH = 0
    SOUTH = 1
    EAST = 2
    WEST = 3

    @property
    def x(self):
        return 0 if self in [self.NORTH, self.SOUTH] else 1 if self == self.EAST else -1

    @property
    def y(self):
        return 0 if self in [self.EAST, self.WEST] else 1 if self == self.NORTH else -1

    def _turn(self, left=True):
        dirs = [self.NORTH, self.EAST, self.SOUTH, self.WEST]
        return dirs[(dirs.index(self) + (-1 if left else 1)) % 4]

    @property
    def left(self):
        return self._turn()

    @property
    def right(self):
        return self._turn(left=False)


direction = Direction.SOUTH
print(direction.y)
print(direction.left)

Production:

-1
Direction.EAST