problem in using metaclasses to inspect Python code

Bengt Richter bokr at oz.net
Fri Dec 13 01:17:44 EST 2002


On 12 Dec 2002 11:36:37 -0800, mis6 at pitt.edu (Michele Simionato) wrote:

>Greg Chapman <glc at well.com> wrote in message news:<60ahvuo3vrru0u9etkdoismti9op5pkel9 at 4ax.com>...
>
><snip beautiful solution>
>
>
>The more I progress with Python, the more I think that is very easy on the
>surface but yet very sophisticated under the hood (which is a good thing, BTW).
>
>You are right that my original problem had nothing to do with metaclasses, so
>I pose you a new one more on topic (there is no limit to my reserve 
>of problems... ;-)
>
>If I write
>
>class Meta(type):
>    def __init__(cls,name,bases,dict):
>        print "%s called me!" % name
>
>class C(object):
>    __metaclass__=Meta
>
>then the output of this program is what you expect:
>
>C called me!
>
>However, if I write
>
>class D(object):
>    pass
>
>D.__metaclass__=Meta
>
>I DON'T obtain what I expect, i.e. "D called me!": the metaclass
>Meta is not automatically called. How do I invoke Meta explicitly ?
>
I suspect the presence of the __metaclass__ class variable is checked
at the end of the execution of the class definition that contains it,
and the call is done at that time. For your class D, there was no
__metaclass__ class variable at the time the execution of the definition
finished. Tacking it on later is too late to trigger the call(s).

You could try something like this maybe:

 >>> class Meta(type):
 ...     def __init__(cls,name,bases,dict):
 ...         print "%s called me!" % name
 ...
 >>> class C(object):
 ...     __metaclass__=Meta
 ...
 C called me!
 >>> class D(object):
 ...     pass
 ...
 >>> MD = Meta(D.__name__, D.__bases__, D.__dict__.copy())
 D called me!
 >>> MD
 <class '__main__.D'>
 >>> md = MD()
 >>> md
 <__main__.D object at 0x007E4720>

Interestingly, that is not dependent on the __metaclass__ hook.

I've been interested in your recent posts re classes and metaclasses.
The idea of a class that produces instances that are also classes is
comfortable, but I am not comfortable with __metaclass__ vis-a-vis
my mental model of metaclass/class relationships.

I've experimented a little with another angle, which I'll post in
a new thread, which I think I'll call "Another way to spell __metaclass__ ?"
In case you're interested.

Regards,
Bengt Richter



More information about the Python-list mailing list