Created
October 10, 2014 03:18
-
-
Save christopherslee/d4b4e999e1c344aedd35 to your computer and use it in GitHub Desktop.
metaclass example with self registering descriptors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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