Aggiornare un altro enum come valore enum in Python? [duplicare]

Sep 18 2020

Supponiamo che io abbia un Python Enum dove ogni istanza di Enum dovrebbe fare riferimento a un'altra istanza della stessa enum. Come lo faccio?

Quando provo qualcosa di simile:

    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

Ottengo un errore che assomiglia un po 'a questo:

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

Ottengo lo stesso problema quando sostituisco "Direction" con "self" nell'esempio precedente.

C'è un modo per fare questo?

Risposte

1 EthanFurman Sep 22 2020 at 05:24

Se non ti dispiace riordinare leggermente il tuo Enum, è abbastanza facile:

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

e in uso:

>>> 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)>

Disclosure: sono l'autore della libreria Python stdlibEnum , enum34backport e Advanced Enumeration ( aenum) .

Grismar Sep 18 2020 at 13:28

Puoi usare il suggerimento di @antont e usare un dizionario, che è perfettamente valido.

Un'altra soluzione, vicina all'originale:

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)

Produzione:

-1
Direction.EAST