7

我正在尝试在 python 中编写一个“枚举类”。我目前遇到的一个小麻烦是无法在枚举类中定义枚举值。也就是说,我可以这样做:

class Fruit:
    def __init__(self, name):
        self.name = name

class Fruits(Enum):
    Apple = Fruit("apple")

但我想这样做,或类似易读的等价物:

class Fruit(Enum):
    def __init__(self, name):
        self.name = name

    Apple = Fruit("apple")

不幸的是,我收到以下错误:未定义名称“水果”

在这种情况下,可见性规则是什么?有什么鲜为人知的 Python 技巧可以帮助我吗?我更喜欢可以在 Enum 的元类中编写的东西,因为这会使用户的使用变得不那么麻烦。

4

1 回答 1

1

你可以制作一个像这样简单的元类:

class MetaEnum(type):
    def __new__(cls, class_name, parents, attrs):
        def __init__(self, name=None):
            if name is not None: self.name = name
        attrs['__init__'] = __init__
        Klass = type.__new__(cls, class_name, parents, attrs)
        if 'instances' in attrs:
            for name in attrs['instances']:
                setattr(Klass, name.capitalize(), Klass(name))
            del Klass.instances # clean up
        return Klass

class Fruit(object):
    __metaclass__ = MetaEnum
    instances = ('apple', 'banana', 'cranberry')

for attr_name in dir(Fruit):
    if not attr_name.startswith('_'):
        attr = getattr(Fruit, attr_name)
        if type(attr) is Fruit:
            print('Fruit.{}, is a Fruit named {}'.format(attr_name, getattr(attr, 'name')))
        else:
            print('Fruit.{}, is a {}'.format(attr, type(attr)))

输出:

Fruit.Apple, is a Fruit named apple
Fruit.Banana, is a Fruit named banana
Fruit.Cranberry, is a Fruit named cranberry
于 2013-04-30T11:42:36.507 回答