Order in metaclass
Peter Otten
__peter__ at web.de
Wed Oct 13 03:04:03 EDT 2004
Nicolas Fleury wrote:
> In the following example:
>
> class MyMetaclass(type): pass
> class MyBaseType(object): __metaclass__ = MyMetaclass
> class MyType(MyBaseType):
> x = 4
> y = 5
> z = 6
>
> Is there any way to modify MyMetaclass to keep the order of x,y,z
> somewhere?
If you want to record the order of these definitions, you need to pass a
custom dictionary that keeps track of assignments in the class generation
code (basically a normal python function comprising the class suite).
Unfortunately that dictionary - which you see later as the classdict
parameter of the metaclass __new__() method - is always a dict created in C,
as was recently discussed on c.l.py (sorry, but all keywords I remember are
'metaclass' and 'martelli' - not very selective :-). Below is my (clumsy)
attempt for a workaround:
import itertools
class OrderedValue(object):
newIndex = itertools.count(1).next
def __init__(self, value):
self.value = value
self.index = self.newIndex()
class Meta(type):
def __new__(mcl, name, bases, classdict):
assert "ordered_names" not in classdict
values = []
for (n, v) in classdict.iteritems():
try:
v, i = v.value, v.index
except AttributeError:
pass
else:
values.append((i, n, v))
values.sort()
ordered_names = []
for (i, n, v) in values:
ordered_names.append(n)
classdict[n] = v
classdict["ordered_names"] = ordered_names
return type.__new__(mcl, name, bases, classdict)
class Base:
__metaclass__ = Meta
class Demo(Base):
alpha = 0
beta = OrderedValue(1)
gamma = OrderedValue(17)
delta = OrderedValue(3)
print Demo.ordered_names
print Demo.alpha, Demo.beta
Peter
More information about the Python-list
mailing list