Python Meta Programming

For an ORM (Object Relational Mapper) I'm working on, I was trying to figure out how I can make it connect to a database without manually calling any functions. Using MySQLdb, you connect to a database by calling MySQLdb.connect(). I wanted this to happen automatically so I'm not always calling MySQLdb.connect() or the equivalent from my own ORM.

The technique I used was to initialize the class when it's first defined. In that __classinit__ method I set up the database connection. The metaclass I used is pretty straightforward:

class MetaRecord(type): 
    def __new__(cls, name, bases, dct): 
        klass = type.__new__(cls, name, bases, dct) 
        klass.__classinit__.im_func(klass) 
        return klass 

The class above is used as the __metaclass__ of another class which has a __classinit__ function that sets up the database connection.

class MySQLRecord(dict): 
    __metaclass__ = MetaRecord 
    __CONN = None 
 
    def __classinit__(cls): 
        if not cls.__CONN: 
            cls.__CONN = MySQLdb.connect(host='localhost', user='foo', passwd='password', db='some_database') 
 
    # ... Rest of the code goes here. 

So now you can create your model classes that inherit from MySQLRecord and it will create a database connection if one doesn't already exist.

class User(MySQLRecord): 
    pass 

I highly encourage anyone interested in python metaprogramming to rip apart these techniques and others to get a better feel of what's going on under the hood. A good place to start would be to set up your own metaclasses and print out the various variables and follow what happens in what order. I'll be doing follow up posts on python metaprogramming that will clear up any fuzzy details.