Skip to content

Instantly share code, notes, and snippets.

@bmihelac
Created November 22, 2012 15:23
Show Gist options
  • Save bmihelac/4131694 to your computer and use it in GitHub Desktop.
Save bmihelac/4131694 to your computer and use it in GitHub Desktop.
Python Metaclass example
"""
Metaclass example
>>> class MyKlass(Klass):
... my_field = Field()
...
... class Meta:
... model = "Model"
...
>>> MyKlass._meta.model
'Model'
>>> 'my_field' in MyKlass.declared_fields
True
"""
class Field(object):
pass
class KlassOptions(object):
model = None
def __new__(cls, meta=None):
overrides = {}
if meta:
for override_name in dir(meta):
if not override_name.startswith('_'):
overrides[override_name] = getattr(meta, override_name)
return object.__new__(type('KlassOptions', (cls,), overrides))
class DeclarativeMetaclass(type):
def __new__(cls, name, bases, attrs):
declared_fields = {}
for field_name, obj in attrs.items():
if isinstance(obj, Field):
field = attrs.pop(field_name)
declared_fields[field_name] = field
attrs['declared_fields'] = declared_fields
new_class = super(DeclarativeMetaclass, cls).__new__(cls, name,
bases, attrs)
opts = getattr(new_class, 'Meta', None)
new_class._meta = KlassOptions(opts)
return new_class
class Klass(object):
__metaclass__ = DeclarativeMetaclass
if __name__ == '__main__':
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment