Slight metaclass confusion
David Mertz
mertz at gnosis.cx
Tue Sep 9 14:14:04 EDT 2003
ben at transversal.com (ben at transversal.com) wrote previously:
|"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:
Read part 2 again. It takes a while to sink in.
Your problem is that you aren't considering the MRO of Class:
>>> class Meta(type):
... def __str__(cls): # Use 'return', not 'print'
... return "I am " + repr(cls)
... def foo(cls):
... return "I am " + repr(cls)
...
>>> Class = Meta("Fish", (), {})
>>> Class.foo()
"I am <class '__main__.Fish'>"
Class is an instance of Meta, just like you expect. Calling the .foo()
method shows this. But when you call a method, the method name is
checked in the -method resolution order- (before the metaclass is
checked):
>>> Class.mro()
[<class '__main__.Fish'>, <type 'object'>]
Fish doesn't define a method .__str__(), so Python looks in Fish's
parent, object. Well, object -does- define, .__str__(), so your call
resolves to:
>>> object.__str__()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: descriptor '__str__' of 'object' object needs an argument
Of course, since object doesn't define a .foo(), resolution proceeds to
the metaclass. If you want to get Class' metaclass method, you can let
Python do the magic for you:
>>> str(Class)
"I am <class '__main__.Fish'>"
Or if you want to be really explicit:
>>> Class.__class__.__str__(Class)
"I am <class '__main__.Fish'>"
Yours, David...
--
_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: Postmodern Enterprises _/_/_/
_/_/ ~~~~~~~~~~~~~~~~~~~~[mertz at gnosis.cx]~~~~~~~~~~~~~~~~~~~~~ _/_/
_/_/ The opinions expressed here must be those of my employer... _/_/
_/_/_/_/_/_/_/_/_/_/ Surely you don't think that *I* believe them! _/_/
More information about the Python-list
mailing list