具有复杂类型的Python枚举

Python enums with complex types

我不熟悉Python,我想知道是否可以用复杂的结构构建枚举,而不仅仅是原始类型。例如(伪代码):

1
2
3
4
5
6
7
8
9
10
Point::Enum
  x, y
  constructor ( x, y ) {
    ...
  }

  bottom_left = Point ( 0, 0 )
  top_left = Point ( 0, 100 )
  top_right = Point ( 100, 100 )
  bottom_right = Point ( 100, 0 )

到目前为止,我只能找到提到带有字符串或int的枚举的python文档。


如果您希望Point作为独立实体,而不是跟踪角点的Enum,则需要将它们分开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from enum import Enum

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return 'Point(%r, %r)' % (self.x, self.y)

class Corner(Enum):
    BottomLeft = Point(0, 0)
    TopLeft = Point(0, 100)
    TopRight = Point(100, 100)
    BottmRight = Point(100, 0)

这样做意味着每个Enum包含一个Point作为其值,但不是Point本身:

1
2
3
4
>>> Corner.BottomLeft
<Corner.BottomLeft: Point(0, 0)>
>>> Corner.BottomLeft.value
Point(0, 0)

如果希望Enum成员是Point成员,则混合Point类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from enum import Enum

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return 'Point(%r, %r)' % (self.x, self.y)

class Corner(Point, Enum):
    BottomLeft = 0, 0
    TopLeft = 0, 100
    TopRight = 100, 100
    BottmRight = 100, 0

>>> Corner.TopLeft
<Corner.TopLeft: (0, 0)>
>>> isinstance(Corner.TopLeft, Point)
True
>>> Corner.TopLeft.value
(0, 100)
>>> Corner.TopLeft.x
0
>>> Corner.TopLeft.y
100

最后,如果您只需要Enum具有xy属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from aenum import Enum

class Corner(Enum):
    __init__ = 'x y'
    BottomLeft = 0, 0
    TopLeft = 0, 100
    TopRight = 100, 100
    BottmRight = 100, 0

>>> Corner.TopLeft
<Corner.TopLeft: (0, 100)>
>>> Corner.TopLeft.value
(0, 100)
>>> Corner.TopLeft.x
0
>>> Corner.TopLeft.y
100

注意,最后一个示例是使用aenum包1。您可以通过为Point类编写__init__来完成与enum34或stdlib Enum相同的事情。

1公开:我是python stdlib Enumenum34backport和advanced enumeration(aenum库的作者。


您可以将它们声明为全局变量,如BOTTOM_LEFTTOP_LEFTTOP_RIGHTBOTTOM_RIGHT

正如你可能知道的,不像其他语言(C++,Java)Python没有的,你只要声明它并且不改变它(绅士的游戏)

然而,亚历克斯·马泰利的配方可以很方便地模仿Python中的const。


试试这个:

1
2
3
4
5
6
7
8
9
10
class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Enum:
    bottom_left = Point(0, 0)
    top_left = Point(0, 100)
    top_right = Point(100, 100)
    bottom_right = Point(100, 0)