Slight metaclass confusion

Hans Nowak hans at zephyrfalcon.org
Tue Sep 9 11:18:00 EDT 2003


ben at transversal.com wrote:
> I am slightly confused about the way metaclasses work, having read
> "Metaclass Programming In Python, Parts 1 and 2"
> 
> I get the fact that the instance of a metaclass is a class, but in
> this case I fail to see why the following does'nt work:

I'm not 100% sure, but:

>>>>class Meta(type):
> 
> ...     def __str__(cls):
> ...             print "I am " + repr(cls)
> ... 
> 
>>>>Class = Meta("Fish", (), {})
>>>>Class.__str__()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> TypeError: descriptor '__str__' of 'object' object needs an argument

...here, you're calling __str__ on a *class*...

>>>>class Simple(object):
> 
> ...     def __str__(self):
> ...             return "I am " + repr(self)
> ... 
> 
>>>>obj = Simple()
>>>>obj.__str__()
> 
> I am <__main__.Simple object at 0x402f676c>

...and here, you're calling it on an *instance*.  The reason it doesn't work 
probably has nothing to do with your metaclass, as demonstrated by this:

 >>> class Foo(object): pass
...
 >>> Foo.__str__()
Traceback (most recent call last):
   File "<input>", line 1, in ?
TypeError: descriptor '__str__' of 'object' object needs an argument
 >>> f = Foo()
 >>> f.__str__()
'<__main__.Foo object at 0x0162C750>'

I'm not sure how it all works internally... using str(Foo) works, but 
Foo.__str__() doesn't.  Notice that Foo.__str__(Foo) does work.

I don't think there's anything wrong with your metaclass (though see below ;-), 
just don't call __str__() directly on the class.

On a side note, it's a bad idea to use 'print' in __str__ or __repr__, even for 
informal test code.  I tried the code above in PyCrust, and it broke the 
automatic attribute lookup.  This is not really important, but it was a 
surprising side effect.

HTH,

-- 
Hans (hans at zephyrfalcon.org)
http://zephyrfalcon.org/







More information about the Python-list mailing list