【问题标题】:Refrencing another enum as an enum value in Python? [duplicate]在 Python 中引用另一个枚举作为枚举值? [复制]
【发布时间】:2020-09-22 06:24:15
【问题描述】:

假设我有一个Python Enum,每个枚举实例都应该引用同一个枚举的另一个实例。我该怎么做?

当我尝试这样的事情时:

    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

我收到一个看起来有点像这样的错误:

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

当我在上面的示例中将“Direction”替换为“self”时,我遇到了同样的问题。

有没有办法做到这一点?

【问题讨论】:

  • 您正试图根据同一枚举 EAST 的另一个值定义枚举值 NORTH,而后者又根据值 NORTH 定义 - 这样的循环定义只能导致问题。你想达到什么目的?因为这里可能有一个很好的 Pythonic 解决方案来解决您的 XY 问题。
  • 我本质上希望能够通过查找我们从当前方向转向的方向的值来“向右”或“向左”。即:new_direction = old_direction.l

标签: python python-3.x object enums


【解决方案1】:

如果您不介意稍微重新排序 Enum,这相当容易:

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

并在使用中:

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

披露:我是 Python stdlib Enumenum34 backportAdvanced Enumeration (aenum) 库的作者。

【讨论】:

  • 不错。我还在考虑添加一点,即声明值很容易,然后在方法中创建结构..但更多地考虑填充字典。正在考虑枚举在其他语言中的表现,我猜是 Java 和 C#。尽管认为它在 Python 中可能有所不同。会检查一下文档,谢谢!
【解决方案2】:

您可以使用@antont 建议并使用字典,这是完全有效的。

另一种解决方案,接近原文:

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)

输出:

-1
Direction.EAST

【讨论】:

    猜你喜欢
    • 2010-12-22
    • 2014-02-16
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多