Advice on metaclass programming
Gonçalo Rodrigues
op73418 at mail.telepac.pt
Mon May 6 17:16:52 EDT 2002
Hi,
I am trying to understand metaclass programming in Python, and to do
that there is nothing better than work out an example. What I had in
mind is a metaclass whose instances (classes) are the Z_n rings of
integers modulo n. Below is a skeleton of such a metaclass. I am seeking
advice (comments, bashing, whatever...) on this, particularly in the
__new__ method of the metaclass where the classes Z_n and their methods
are generated - I'm a bit uneasy on this matter. Are there more pythonic
ways to dynamically generate methods?
TIA and best regards,
Gonçalo Rodrigues
PS: Eventually, when the metaclass is fully fleshed out, I will post the
code in the ActiveState cookbook as an example in metaclass programming.
PS-to-PS: Just a curiosity: Field(2) gives the Boolean ring...
-----BEWARE: PYTHON CODE AHEAD----
"""
A module for finite arithmetic.
"""
from __future__ import generators
#The simplest prime-detection algorithm possible.
def IsPrime(n):
if isinstance(n, int) and n >= 1:
for i in range(2, n):
if n%i == 0:
return 0
return 1
else:
raise TypeError, "%s is not an integer >= 1." % str(n)
class Field(type):
"""The Finite Field metaclass.
For each integer n > 1, Field(n) returns the finite ring (class) of
integers modulo n."""
def __new__(cls, n):
if isinstance(n, int) and n > 1:
#Initialitze methods dictionary.
meth = {}
#Add the necessary methods one by one.
#Initializer.
def new(kls, m):
if isinstance(m, int):
return m%n
else:
raise TypeError, "%s is not an integer." % str(m)
meth["__new__"] = staticmethod(new)
#String representation.
def strrep(m):
return str(m)
meth["__str__"] = strrep
#Numeric methods
#If n is prime add division.
if IsPrime(n):
pass #Snipped code...
return type.__new__(cls, "Z_%d" % n, (int,), meth)
else:
raise TypeError, "%s is not an integer > 1." % str(n)
def __init__(self, n):
#Generate docstring.
self.__doc__ = """The Z(%d) finite field.""" % n
def __str__(self):
return self.__name__
def __len__(self):
return int(self.__name__[2:])
#The iterator protocol for the class.
def __iter__(self):
for i in range(len(self)):
yield self(i)
def ToList(self):
"""Return a list with all the elements of the class."""
return [i for i in self]
#Some test code.
if __name__ == "__main__":
#Test classes.
for i in range(2, 20):
temp = Field(i)
print "This is the finite ring ", temp, " located at %d" %
id(temp)
print temp.ToList()
More information about the Python-list
mailing list