simple metaclass question

Carl Banks imbosol at vt.edu
Tue Nov 12 18:17:00 EST 2002


Blair Hall wrote:
> Please don't ask me why, but in trying to use metaclasses
> I simplified my code to the following:
> 
> class M(object):
>    def __init__(cls,name, bases,dict):
>        cls.val=0
> 
>    def set(cls,n):
>        cls.val = n
> 
> class A(object):
>    __metaclass__ = M
>    val = 3


I'm trying to get the hang of this metaclass thing myself.  Let me see
if I can interpret.

The definition of class A essentially (and maybe really) becomes the
following assignment:

A = M("A", (object,), {'val': 3, '__metaclass__': M})

What does this do?  Well, M, being a class, when called, returns an
instance of class M.  So that is what A is bound to.  There are two
problems then:

1. You initialized cls.val in M's __init__ to zero, but you probably
   should have initilized cls.val to dict['val'].

2. Because M is not a subclass of type, instances of M are not types.
   Therefore, A is not a type.  (I'm not sure of this one, though.  I
   think in Python an object can be a type only if it is a subclass of
   type; I'm not sure if this is true in other languages with
   metaobjects.)


> I was then surprised to see that
>>>> A.val
> 0

This is because A is bound to a instance of the class M.  Because you
initialized the val attribute of the instance to zero, and A is bound
to the instance, A.val is zero.

Here is something that probably does what you expected:

class M(type):
    def __init__(self,name,bases,dict):
        self.val = dict['val']
    def set(self,n):
        self.val = n



-- 
CARL BANKS



More information about the Python-list mailing list