__name__ on new-style classes

Gonçalo Rodrigues op73418 at mail.telepac.pt
Wed Apr 3 13:16:29 EST 2002


On Wed, 03 Apr 2002 17:52:22 +0100, Gonçalo Rodrigues
<op73418 at mail.telepac.pt> wrote:

>On Wed, 03 Apr 2002 01:53:56 GMT, Guido van Rossum <guido at python.org>
>wrote:
>
>>"Gonçalo Rodrigues" wrote:
>>> 
>>> On Mon, 01 Apr 2002 02:35:47 GMT, Guido van Rossum <guido at python.org>
>>> wrote:
>>> 
>>> >It's a feature.  The reason for the change is that I've never seen an
>>> >example of a use for it (as opposed to changing an instance's __class__).
>>> >If you have one, let us know.
>>> 
>>> I bumped into this "feature" a few days ago trying to understand
>>> metaclasses in Python. And to understand them there is nothing better
>>> than actually coding one, so I'll explain my problem/solution and let
>>> you judge if this is a good use case for having a writable __name__.
>>> 
>>> My problem is modelling finite arithmetic in Python. Here by finite
>>> arithmetic I mean all the quotients of the integer ring Z. There is a
>>> countable number of them, one for each n > 1 (n=0 is Z and n=1 is the
>>> trivial ring {0}. If n is negative then it is the same as -n). If n is
>>> prime then we actually have a field.
>>> 
>>> The obvious way (to me, that is) to do this is to let each finite ring
>>> Z_n be a class, inheriting from int. Since there are an infinite number
>>> of these we have to have a metaclass, call it Field, that has as
>>> intances the Z_n rings, e.g. Z_n would be Field(n). The skeleton of this
>>> metaclass would be something like:
>>> 
>>> class Field(type):
>>>     """The Finite Field metaclass."""
>>> 
>>>     def __new__(cls, n):
>>>         if isinstance(n, int) and n > 1:
>>>             #The template class.
>>>             class Z(int):
>>>                 pass
>>> 
>>>             #Generate proper name for the instance class, e.g. "Z_n"
>>>             Z.__name__ = "Z_%d" % n
>>> 
>>>             #Return class.
>>>             return Z
>>>         else:
>>>             raise TypeError, "%s is not an integer > 1." % str(n)
>>> 
>>> If I cant write to __name__ then all the instances will have the same
>>> name... Not A Good Thing, IMHO.
>>
>>But you're doing the meta-instantiation all wrong.  Rather than using a
>>class
>>statement, you should be using cls.__new__(cls, "Z_%d"%n, (int,), {...}).
>>
>>--Guido van Rossum (home page: http://www.python.org/~guido/)
>
>Thanks for the correction. I should have figured that one out. Still,
>shouldn't it be
>
>type.__new__(cls, "Z_%d" % n, (int,), {...})
>
>(instantiating the type class not the cls class) Btw, could you tell me
>what is inherently wrong in generating classes with a class statement?
>Could the generated class somehow behave improperly?

Forget it. I've been reading the descintro and it becomes kinda obvious.
>
>All the best,
>Gonçalo Rodrigues

Thaks anyway,
Gonçalo Rodrigues




More information about the Python-list mailing list