Should __metaclass__ force the use of a metaclass in Python?

I am trying to learn about metaclasses in Python. I get the basic idea, but I cannot activate the mechanism. As I understand it, you can specify M as a metaclass when building class K by setting __metaclass__ to M at the global or class level. To test this, I wrote the following program:

 p = print class M(type): def __init__(*args): type.__init__(*args) print("The rain in Spain") p(1) class ClassMeta: __metaclass__ = M p(2) __metaclass__ = M class GlobalMeta: pass p(3) M('NotMeta2', (), {}) p(4) 

However, when I run it, I get the following output:

  C: \ Documents and Settings \ Daniel Wong \ Desktop> python --version
 Python 3.0.1

 C: \ Documents and Settings \ Daniel Wong \ Desktop> python meta.py
 one
 2
 3
 The rain in Spain
 4

Can't I see "rain in Spain" after 1 and 2? What's going on here?

+6
python oop metaclass
source share
3 answers

In Python 3 (which you use), metaclasses are specified by the keyword parameter in the class definition:

 class ClassMeta(metaclass=M): pass 

Specifying a property of the __metaclass__ class or a global variable is an old syntax from Python 2.x and is no longer supported. See Also What's New in Python 3 and PEP 2115 .

+13
source share

This works as you would expect in Python 2.6 (and earlier), but in 3.0 metaclasses are set differently:

 class ArgMeta(metaclass=M): ... 
+2
source share

Metaclass syntax changed in Python 3.0. The __metaclass__ attribute __metaclass__ no longer special for the class or module level. To do what you are trying to do, you need to specify metaclass as the keyword argument in the class statement:

 p = print class M(type): def __init__(*args): type.__init__(*args) print("The rain in Spain") p(1) class ClassMeta(metaclass=M): pass 

Productivity:

 1 The rain in Spain 

As expected.

+2
source share

All Articles