I am trying to write an "enum class" in python. A slight nuisance I am currently experiencing is the inability to define enum values inside the enum class. That is, I can do this:
class Fruit:
    def __init__(self, name):
        self.name = name
class Fruits(Enum):
    Apple = Fruit("apple")
But I would like to do this, or a similarly legible equivalent:
class Fruit(Enum):
    def __init__(self, name):
        self.name = name
    Apple = Fruit("apple")
Unfortunately, I am getting the following error: name 'Fruit' is not defined
What are the rules of visibility in such a case? Are there any little-known Python tricks that could help me? I would prefer something that is possible to write in the metaclass of Enum, since that would make usage less cumbersome for the user.
You could make a metaclass that did something simple like this:
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)))
Output:
Fruit.Apple, is a Fruit named apple
Fruit.Banana, is a Fruit named banana
Fruit.Cranberry, is a Fruit named cranberry
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With