Unexpected __metaclass__ method behavior

Michele Simionato michele.simionato at gmail.com
Sun Dec 30 07:09:25 EST 2007



anne.nospa... at wangnick.de wrote:
> Dear fellow Pythonians,
>
> I just stumbled upon the following unexpected behavior:
>
> class TestType(type):
>     def Foo(self): return 'TestType Foo'
> class Test(object):
>     __metaclass__ = TestType
>     def Foo(self): return 'Test Foo'
> t = Test()
> print t.Foo()
> print Test.Foo()
>
> This will produce:
> Test Foo
> Traceback (most recent call last):
>   File "test.py", line 8, in <module>
>     print Test.Foo()
> TypeError: unbound method Foo() must be called with Test instance as
> first argument (got nothing instead)
>
> I can imagine why this is happening, and that there is no easy
> solution, but it is not what I was expecting.
>
> Anybody willing to explain the details of what's exactly going on
> during the method lookup of Test.Foo?

The regular method is checked for *before* the metaclass method.
You must use

type(Test).Foo(Test)

to call the method. It is clear that it must be that way: when you do
(for instance)
SomeClass.__init__ you do not expect to have type.__init__(SomeClass)
called.
Notice that *all* classes have a metaclass, by default "type" for new-
style
classes and "ClassType" for old-style ones.

     Michele Simionato



More information about the Python-list mailing list