Skip to content

Instantly share code, notes, and snippets.

@jbvsmo
Last active December 13, 2015 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbvsmo/4958012 to your computer and use it in GitHub Desktop.
Save jbvsmo/4958012 to your computer and use it in GitHub Desktop.
Creating Enums with getattr syntax.
'''
>>> Enum.Colors.red.green.blue()
<Enum: Colors>
>>> Colors.red
<Colors.red = 0>
>>> Colors.green
<Colors.green = 1>
>>> Colors.blue
<Colors.blue = 2>
'''
class MetaEnum(type):
def __getattr__(cls, name):
obj = type(name, (BaseEnum,), {})
globals()[name] = obj
return obj
class Enum(metaclass=MetaEnum):
pass
class MetaBaseEnum(type):
def __init__(cls, *args):
type.__init__(cls, *args)
cls._items = {}
cls._cnt = 0
cls._accept = True
def __getattr__(cls, name):
obj = cls._items.get(name)
if obj:
return obj
if cls._accept:
cls(name)
return cls
raise AttributeError(name)
def __call__(cls, value=None):
if value is None:
cls._accept = False
return cls
else:
return super().__call__(value)
def __repr__(cls):
return '<Enum: {}>'.format(cls.__name__)
class BaseEnum(metaclass=MetaBaseEnum):
def __new__(cls, name):
obj = cls._items.get(name)
if obj is not None:
return obj
obj = object.__new__(cls)
cls._items[name] = obj
return obj
def __init__(self, name):
self.name = name
self.val = type(self)._cnt
type(self)._cnt += 1
def __repr__(self):
return '<{0.__class__.__name__}.{0.name} = {0.val}>'.format(self)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment