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