By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,965 Members | 1,962 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,965 IT Pros & Developers. It's quick & easy.

parameterized metaclass (or metametaclass)

P: n/a

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.
Jul 18 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
> I was wondering if there is some simpler way of building
parameterized
metaclasses ?


Why not just a function returning metaclasses?

def metaFactory(*args):
dic = <something possibly depending on args>
return type("somemetaclass", (type,), dic)

Alternatively, a metaclass classmethod returning a metaclass, so that
you can use something like

__metaclass__ = MyMetaclass.with(*args) # classmethod returning a
metaclass

Michele Simionato

Jul 18 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.