Skip to content

Instantly share code, notes, and snippets.

@christopherslee
Created October 10, 2014 03:18
Show Gist options
  • Save christopherslee/d4b4e999e1c344aedd35 to your computer and use it in GitHub Desktop.
Save christopherslee/d4b4e999e1c344aedd35 to your computer and use it in GitHub Desktop.
metaclass example with self registering descriptors
class Field(object):
def __init__(self, name):
self._name = name
def __get__(self, instance, owner):
return instance._data[self._name]
def __set__(self, instance, value):
instance._data[self._name] = value
class IntegerField(Field):
pass
class StringField(Field):
pass
class ModelMeta(type):
_registry = {}
def __new__(cls, name, bases, attrs):
for n, v in attrs.items():
if isinstance(v, Field):
if name not in cls._registry:
cls._registry[name] = []
cls._registry[name].append(n)
return super(ModelMeta, cls).__new__(cls, name, bases, attrs)
class Model(object):
__metaclass__ = ModelMeta
def __init__(self):
self._data = {}
def fields(self):
return ModelMeta._registry[self.__class__.__name__]
def __repr__(self):
str = "<%s " % self.__class__.__name__
fields = []
for field in ModelMeta._registry[self.__class__.__name__]:
fields.append("%s=%s" % (field, getattr(self, field)))
str += ", ".join(fields)
str += ">"
return str
class Circle(Model):
diameter = StringField('diameter')
class Square(Model):
width = StringField('width')
if __name__ == '__main__':
model = Circle()
model.diameter = 1
print model.diameter
print model
print model.fields()
square = Square()
square.width = 5
print square
print square.fields()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment