Metaclasses are a way for you to have a class act as the template for another class. They are simlar to a classfactory,
in that they create new classes. In words of Tim Peters Metaclasses are deeper magic than 99% of people are going to need.
However, in right hands they can be a potent tool, in particular Django uses metaclasses beautifully to create very beautiful declarative models. Without further ado, here is a very simple (and very wrong) metaclass example.
class Z(type):
def __new__(cls, name, bases, attrs, ):
print cls, name, bases, attrs
class A(object):
__metaclass__ = Z
print A
print A()
Running this gives this output.
shabda@shabda-laptop ~/docs> python testmetaclass.py
<class '__main__.Z'> A (<type 'object'>,) {'__module__': '__main__', '__metaclass__': <class '__main__.Z'>}
None
Traceback (most recent call last):
File "testmetaclass.py", line 14, in <module>
print A()
TypeError: 'NoneType' object is not callable
Let what happened,
print cls, name, bases, attrsgot executed, even though we are not creatingZor calling it anywhere.print AprintedNoneprint A()failed with a traceback
Lets try a slightly modified file,http://uswaretech.com/blog/2009/11/the-magic-of-metaclasses-in-python/
class Z(type):
def __new__(cls, name, bases, attrs, ):
return str
class A(object):
__metaclass__ = Z
This gives me,
print A
print A('Hello')
shabda@shabda-laptop ~/docs> python testmetaclass.py
<type 'str'>
Hello
shabda@shabda-laptop ~/docs>
The output suggests that A is behaving like str. This should lead us to a few conclusions,
- If a class has a
__metaclass__, it is replaced by another class. - The function called for creating the new class is
__new__, it takes 4 parameters. - cls is the metaclass being called, name is the name of the original class, bases are bases for original class, and attrs are attributes from original class.
- The old class is set to the value returned from
__metaclass__.__new__ - As we returned nothing in the first snippet,
Awas set to None. In second snippet it was set tostr.
Here is an actual metaclass being used by Django.
- In line 24,
Form. __metaclass__is set toDeclarativeFieldsMetaclass DeclarativeFieldsMetaclassis a subclass oftype.- It defines a method called as
__new__which returns the newly created class.
And that is all there is to metaclasses!
This is the first in the series of short and sweet Django posts we are going to do. You are interested, right. Do follow us on twitter or subscribe to our feed.
We build Amazing We Apps. Talk to us or email us at sales@uswaretech.com .
Related posts:

{ 1 trackback }
{ 25 comments… read them below or add one }
http://uswaretech.com/blog/2009/11/the-magic-of-metaclasses-in-python/ The magic of metaclasses in Python
This comment was originally posted on Twitter
The magic of metaclasses in Python: http://bit.ly/7dzfzu
This comment was originally posted on Twitter
The magic of metaclasses in Python — The Usware Blog – Django Web…: Bookmark this on Delicious – Saved by hi.. http://bit.ly/4wTkpQ
This comment was originally posted on Twitter
Never have to use metaclass in Python, but the tutorial is clear and good. RT @programmingjoy http://bit.ly/8bDcSa
This comment was originally posted on Twitter
Never have to use metaclass in Python, but the tutorial is clear and good. RT #python #programming @programmingjoy http://bit.ly/8bDcSa
This comment was originally posted on Twitter
programmingjoy: The magic of metaclasses in Python [Tutorial] #programming http://bit.ly/8bDcSa http://ff.im/-bOwkY
This comment was originally posted on Twitter
http://bit.ly/5lDWL6 “programmingjoy: The magic of metaclasses in Python [Tutorial] #programming http://bit.ly/8bDcSa http://ff.im/-bOwkY”;
This comment was originally posted on Twitter
Brain hurting ouch
This comment was originally posted on Reddit
Metaclasses are objects that can be used to customize class creation, they are not used as "templates" for the objects they create. The fact they can be abused to create "nice syntax" for things like defining database models is a side effect of their function. In the case of every ORM I’ve seen that abuses metaclasses, you are left with a chunk of the implementation that can’t be accessed cleanly without using Python syntax. This leaves you with few options if you want to build a new class at runtime, usually by putting a class definition in a function, something like: def make_class(…): class Foo(SomeMagicClass): someFixedName = … return Foo This is bad enough already, but as you can see, there is no convenient way to chose "someFixedName" at runtime. So you might end up with: def make_class(…): eval(”’ class %s(SomeMagicClass): %s = … return Foo ”’ % (name, someFixedName), globals(), locals()) return locals()[name] Alternatively your solution might include a simpler second interface for building things at runtime, but this is just worse. Two interfaces for doing the same thing, depending on when you happen to do it?
This comment was originally posted on Reddit
Reddit/p: The magic of metaclasses in Python [Tutorial] http://bit.ly/5lAjyx
This comment was originally posted on Twitter
tl;dr metaclasses suck. DONT USE THEM. etc.
This comment was originally posted on Reddit
Stay clear of metaclasses. Use class decorators instead!
This comment was originally posted on Reddit
I use python regularly, and I must say metaclasses are one of the most stupid programming language concepts introduced in quite some time. As if the multiple-inheritance python object model was not broken and painful enough already, that they had to make it about a dozen magnitude orders more complex… *sigh* If I wanted to show off at how ’smart’ I am by using byzantine features, I would use C++, thank you very much.
This comment was originally posted on Reddit
Home from Scratch with #VendAsta and reading about python metaclasses http://bit.ly/4IhnZe/
This comment was originally posted on Twitter
Metaclasses are not something to be used lightly, especially since factory functions and (in 2.6+) class decorators let you accomplish almost all the same things in a much cleaner fashion. Or, more generally, if you’re wondering whether you need metaclasses, you don’t. When you really need the feature, you’ll know because all the other things you’ll have tried first will have failed to do what you needed.
This comment was originally posted on Reddit
But there are differences between class decorators and metaclasses as noted in [this PyCon paper (PDF!)](http://us.pycon.org/media/2009/talkdata/PyCon2009/055/decos_and_metas_pycon.pdf). Also [this blog](http://jackdied.blogspot.com/2008/09/pycon-uk-class-decorators-radically.html) has a useful part in the discussions on the concept that "decorators are once and metaclasses are always".
This comment was originally posted on Reddit
As noted by Tim Peters: "Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t." I have programmed in python for > 10 years, and I’ve never missed this particular feature. However it is one of those things that you really want bad if you need it.
This comment was originally posted on Reddit
> However it is one of those things that you really want bad if you need it. That is what the people that like to feel smug and smarter than everyone else likes to claim, I have seen zero real evidence of it being true.
This comment was originally posted on Reddit
The magic of metaclasses in Python #beginner_stuff http://ff.im/-bROQu
This comment was originally posted on Twitter
http://twitter.com/dnene/statuses/5967341354 “The magic of metaclasses in Python #beginner_stuff http://ff.im/-bROQu”;
This comment was originally posted on Twitter
And *amen* to that. Metaclasses are evil and stupid, stay away from them.
This comment was originally posted on Reddit
The magic of metaclasses in Python — The Usware Blog – Django Web…: Bookmark this on Delicious – Saved by al.. http://bit.ly/07PaffX
This comment was originally posted on Twitter
you are dumb
This comment was originally posted on Reddit
I know, thank you for the compliment.
This comment was originally posted on Reddit
The magic of metaclasses in Python — The Usware Blog – Django Web…: Bookmark this on Delicious – Saved by … http://bit.ly/5c4egA
This comment was originally posted on Twitter