It's not so hard as you'd think
# Crack fingers
# File orm.py:
belongs_to_gatherer = []
def belongs_to(what):
belongs_to_gatherer.append(what)
has_many_gatherer = []
def has_many(what):
has_many_gatherer.append(what)
class MetaRecord(type):
def __new__(cls, name, bases, dictionary):
global belongs_to_gatherer, has_many_gatherer
Record = super(MetaRecord, cls).__new__(cls, name, bases, dictionary)
# Now we grab what we've gathered and run the respective methods on them:
for i in belongs_to_gatherer:
Record.belongs_to(i)
belongs_to_gatherer = []
for i in has_many_gatherer:
Record.has_many(i)
has_many_gatherer = []
return Record
class ActiveRecord(object):
__metaclass__ = MetaRecord
@classmethod
def belongs_to(cls, what):
# Set it to belong to: what
print cls, "belongs to", what
@classmethod
def has_many(cls, what):
# Set it to have many: what
print cls, "has many", what
__all__ = [ActiveRecord, belongs_to, has_many]
# In another file:
from orm import *
class Person(ActiveRecord):
belongs_to('project_manager')
has_many('milestones')
Note that all these examples (this is the third along these lines) require cooperation on the part of the class. I hadn't really considered that, but it is different from Zope's implements() which can be applied to any class without any cooperation on the part of that class.
# Ian Bicking
I liked that! Pretty cool. What about?
- def belongs_to_classmethod(cls, what):
- print cls.__name__, " Belongs to ", what
- class MetaActiveRecord(type):
- def __new__(cls, name, bases, dictionary):
Record = super(MetaActiveRecord, cls).__new__(cls, name, bases, dictionary)
- if dictionary.has_key('belongs_to'):
- Record.belongs_to_classmethod = classmethod(belongs_to_classmethod) Record.belongs_to_classmethod(dictionary['belongs_to'])
return Record
- class ActiveRecord(object):
- __metaclass__ = MetaActiveRecord
- class Person(ActiveRecord):
belongs_to = 'project_manager' def __init__(self):
print "Person __init__"a = Person()
prints: Person Belongs to project_manager Person __init__
# Gordon Scott