Hi, I've been looking at writing parameterized metaclasses and here are the two solutions I've come to: (my goal was to build a way to automatically add a hash function that would take into account a selected list of object attributes)
1. all-in-one metametaclass: class Autohash2(type): """ Metametaclass that instantiates into a metaclass creating a hash function based on the attributes passed on instantiation. """ def __new__(cls, hash_attributes): def class_new(cls, name, bases, d): print "New class", name l = hash_attributes _hash = hash _tuple = tuple c = _hash(_tuple([_hash(k) for k in l])) def object_hash(obj): g = obj.__getattribute__ return _hash(_tuple([_hash(g(k)) for k in l])) d['__hash__'] = object_hash return super(Autohash2, cls).__new__(cls, name, bases, d) name = '__private' bases = (type,) d = {'__new__': class_new} print "New metaclass", name return type.__new__(cls, name, bases, d) 2. with the metametaclass property slightly abstracted away: class Metametaclass(type): def __new__(cls, name, bases, dict_): d = { '__new__': dict_['class_new'] } def meta_new(cls, *args, **kargs): print "New metaclass" name = '__private' bases = (type,) return super(Metametaclass, cls).__new__(cls, name, bases, d) dict_['__new__'] = meta_new print "New metametaclass", name return type.__new__(cls, name, bases, dict_) class Autohash(type): __metaclass__ = Metametaclass def __init__(cls, hash_attributes): cls.hash_attributes = hash_attributes def class_new(cls, name, bases, d): print "New class", name l = cls.hash_attributes _hash = hash _tuple = tuple c = _hash(_tuple([_hash(k) for k in l])) def object_hash(obj): g = obj.__getattribute__ return _hash(_tuple([_hash(g(k)) for k in l])) d['__hash__'] = object_hash return super(Autohash, cls).__new__(cls, name, bases, d) Both of those metametaclasses can be used (successfully!) in the following way: class Address(object): __metaclass__ = Autohash3(('host', 'port')) # <snip rest of class definition> a = Address() a.host = 'localhost' a.port = 5555 b = copy.copy(a) hash(a) == hash(b) I was wondering if there is some simpler way of building parameterized metaclasses ? Regards Antoine. -- http://mail.python.org/mailman/listinfo/python-list