Related Questions
Sponsored Content
41 Answered Questions
25 Answered Questions
26 Answered Questions
[SOLVED] Does Python have a ternary conditional operator?
- 2008-12-27 08:32:18
- Devoted
- 1604949 View
- 4979 Score
- 26 Answer
- Tags: python operators ternary-operator conditional-operator python-2.5
27 Answered Questions
[SOLVED] What does if __name__ == "__main__": do?
- 2009-01-07 04:11:00
- Devoted
- 2110583 View
- 4727 Score
- 27 Answer
- Tags: python namespaces main python-module idioms
25 Answered Questions
[SOLVED] How can I safely create a nested directory in Python?
- 2008-11-07 18:56:45
- Parand
- 2163066 View
- 3379 Score
- 25 Answer
- Tags: python exception path directory operating-system
55 Answered Questions
[SOLVED] Calling an external command in Python
- 2008-09-18 01:35:30
- freshWoWer
- 2885328 View
- 4050 Score
- 55 Answer
- Tags: python shell command subprocess external
32 Answered Questions
23 Answered Questions
[SOLVED] What is the difference between @staticmethod and @classmethod?
- 2008-09-25 21:01:57
- Daryl Spitzer
- 637246 View
- 2973 Score
- 23 Answer
- Tags: python oop methods python-decorators
7 Answered Questions
[SOLVED] Understanding Python super() with __init__() methods
- 2009-02-23 00:30:08
- Mizipzor
- 1436599 View
- 2155 Score
- 7 Answer
- Tags: python class oop inheritance super
8 Answered Questions
[SOLVED] Getting the class name of an instance?
- 2009-02-04 11:37:48
- Dan
- 685682 View
- 1136 Score
- 8 Answer
- Tags: python introspection instanceof python-datamodel
15 comments
@e-satis 2011-07-05 11:29:50
Classes as objects
Before understanding metaclasses, you need to master classes in Python. And Python has a very peculiar idea of what classes are, borrowed from the Smalltalk language.
In most languages, classes are just pieces of code that describe how to produce an object. That's kinda true in Python too:
But classes are more than that in Python. Classes are objects too.
Yes, objects.
As soon as you use the keyword
class
, Python executes it and creates an OBJECT. The instructioncreates in memory an object with the name "ObjectCreator".
This object (the class) is itself capable of creating objects (the instances), and this is why it's a class.
But still, it's an object, and therefore:
e.g.:
Creating classes dynamically
Since classes are objects, you can create them on the fly, like any object.
First, you can create a class in a function using
class
:But it's not so dynamic, since you still have to write the whole class yourself.
Since classes are objects, they must be generated by something.
When you use the
class
keyword, Python creates this object automatically. But as with most things in Python, it gives you a way to do it manually.Remember the function
type
? The good old function that lets you know what type an object is:Well,
type
has a completely different ability, it can also create classes on the fly.type
can take the description of a class as parameters, and return a class.(I know, it's silly that the same function can have two completely different uses according to the parameters you pass to it. It's an issue due to backwards compatibility in Python)
type
works this way:e.g.:
can be created manually this way:
You'll notice that we use "MyShinyClass" as the name of the class and as the variable to hold the class reference. They can be different, but there is no reason to complicate things.
type
accepts a dictionary to define the attributes of the class. So:Can be translated to:
And used as a normal class:
And of course, you can inherit from it, so:
would be:
Eventually you'll want to add methods to your class. Just define a function with the proper signature and assign it as an attribute.
And you can add even more methods after you dynamically create the class, just like adding methods to a normally created class object.
You see where we are going: in Python, classes are objects, and you can create a class on the fly, dynamically.
This is what Python does when you use the keyword
class
, and it does so by using a metaclass.What are metaclasses (finally)
Metaclasses are the 'stuff' that creates classes.
You define classes in order to create objects, right?
But we learned that Python classes are objects.
Well, metaclasses are what create these objects. They are the classes' classes, you can picture them this way:
You've seen that
type
lets you do something like this:It's because the function
type
is in fact a metaclass.type
is the metaclass Python uses to create all classes behind the scenes.Now you wonder why the heck is it written in lowercase, and not
Type
?Well, I guess it's a matter of consistency with
str
, the class that creates strings objects, andint
the class that creates integer objects.type
is just the class that creates class objects.You see that by checking the
__class__
attribute.Everything, and I mean everything, is an object in Python. That includes ints, strings, functions and classes. All of them are objects. And all of them have been created from a class:
Now, what is the
__class__
of any__class__
?So, a metaclass is just the stuff that creates class objects.
You can call it a 'class factory' if you wish.
type
is the built-in metaclass Python uses, but of course, you can create your own metaclass.The
__metaclass__
attributeIn Python 2, you can add a
__metaclass__
attribute when you write a class (see next section for the Python 3 syntax):If you do so, Python will use the metaclass to create the class
Foo
.Careful, it's tricky.
You write
class Foo(object)
first, but the class objectFoo
is not created in memory yet.Python will look for
__metaclass__
in the class definition. If it finds it, it will use it to create the object classFoo
. If it doesn't, it will usetype
to create the class.Read that several times.
When you do:
Python does the following:
Is there a
__metaclass__
attribute inFoo
?If yes, create in memory a class object (I said a class object, stay with me here), with the name
Foo
by using what is in__metaclass__
.If Python can't find
__metaclass__
, it will look for a__metaclass__
at the MODULE level, and try to do the same (but only for classes that don't inherit anything, basically old-style classes).Then if it can't find any
__metaclass__
at all, it will use theBar
's (the first parent) own metaclass (which might be the defaulttype
) to create the class object.Be careful here that the
__metaclass__
attribute will not be inherited, the metaclass of the parent (Bar.__class__
) will be. IfBar
used a__metaclass__
attribute that createdBar
withtype()
(and nottype.__new__()
), the subclasses will not inherit that behavior.Now the big question is, what can you put in
__metaclass__
?The answer is: something that can create a class.
And what can create a class?
type
, or anything that subclasses or uses it.Metaclasses in Python 3
The syntax to set the metaclass has been changed in Python 3:
i.e. the
__metaclass__
attribute is no longer used, in favor of a keyword argument in the list of base classes.The behaviour of metaclasses however stays largely the same.
One thing added to metaclasses in python 3 is that you can also pass attributes as keyword-arguments into a metaclass, like so:
Read the section below for how python handles this.
Custom metaclasses
The main purpose of a metaclass is to change the class automatically, when it's created.
You usually do this for APIs, where you want to create classes matching the current context.
Imagine a stupid example, where you decide that all classes in your module should have their attributes written in uppercase. There are several ways to do this, but one way is to set
__metaclass__
at the module level.This way, all classes of this module will be created using this metaclass, and we just have to tell the metaclass to turn all attributes to uppercase.
Luckily,
__metaclass__
can actually be any callable, it doesn't need to be a formal class (I know, something with 'class' in its name doesn't need to be a class, go figure... but it's helpful).So we will start with a simple example, by using a function.
Now, let's do exactly the same, but using a real class for a metaclass:
But this is not really OOP. We call
type
directly and we don't override or call the parent__new__
. Let's do it:You may have noticed the extra argument
upperattr_metaclass
. There is nothing special about it:__new__
always receives the class it's defined in, as first parameter. Just like you haveself
for ordinary methods which receive the instance as first parameter, or the defining class for class methods.Of course, the names I used here are long for the sake of clarity, but like for
self
, all the arguments have conventional names. So a real production metaclass would look like this:We can make it even cleaner by using
super
, which will ease inheritance (because yes, you can have metaclasses, inheriting from metaclasses, inheriting from type):Oh, and in python 3 if you do this call with keyword arguments, like this:
It translates to this in the metaclass to use it:
That's it. There is really nothing more about metaclasses.
The reason behind the complexity of the code using metaclasses is not because of metaclasses, it's because you usually use metaclasses to do twisted stuff relying on introspection, manipulating inheritance, vars such as
__dict__
, etc.Indeed, metaclasses are especially useful to do black magic, and therefore complicated stuff. But by themselves, they are simple:
Why would you use metaclasses classes instead of functions?
Since
__metaclass__
can accept any callable, why would you use a class since it's obviously more complicated?There are several reasons to do so:
UpperAttrMetaclass(type)
, you know what's going to follow__new__
,__init__
and__call__
. Which will allow you to do different stuff. Even if usually you can do it all in__new__
, some people are just more comfortable using__init__
.Why would you use metaclasses?
Now the big question. Why would you use some obscure error prone feature?
Well, usually you don't:
Python Guru Tim Peters
The main use case for a metaclass is creating an API. A typical example of this is the Django ORM.
It allows you to define something like this:
But if you do this:
It won't return an
IntegerField
object. It will return anint
, and can even take it directly from the database.This is possible because
models.Model
defines__metaclass__
and it uses some magic that will turn thePerson
you just defined with simple statements into a complex hook to a database field.Django makes something complex look simple by exposing a simple API and using metaclasses, recreating code from this API to do the real job behind the scenes.
The last word
First, you know that classes are objects that can create instances.
Well in fact, classes are themselves instances. Of metaclasses.
Everything is an object in Python, and they are all either instances of classes or instances of metaclasses.
Except for
type
.type
is actually its own metaclass. This is not something you could reproduce in pure Python, and is done by cheating a little bit at the implementation level.Secondly, metaclasses are complicated. You may not want to use them for very simple class alterations. You can change classes by using two different techniques:
99% of the time you need class alteration, you are better off using these.
But 98% of the time, you don't need class alteration at all.
@Max Goodridge 2017-04-12 13:18:59
It appears that in Django
models.Model
it does not use__metaclass__
but ratherclass Model(metaclass=ModelBase):
to reference aModelBase
class which then does the aforementioned metaclass magic. Great post! Here's the Django source: github.com/django/django/blob/master/django/db/models/…@Spybdai 2017-04-20 03:24:08
what if indicate different metaclass in both base and derived class?
@petrux 2017-04-25 21:32:44
<<Be careful here that the
__metaclass__
attribute will not be inherited, the metaclass of the parent (Bar.__class__
) will be. IfBar
used a__metaclass__
attribute that createdBar
withtype()
(and nottype.__new__()
), the subclasses will not inherit that behavior.>> -- Could you/someone please explain a bit deeper this passage?@TBBle 2017-06-13 13:22:27
@MaxGoodridge That's the Python 3 syntax for metaclasses. See Python 3.6 Data model VS Python 2.7 Data model
@Deep 2017-06-25 14:43:54
echoing @petrux question. I was lost at the statement:
Be careful here that the __metaclass__ attribute will not be inherited, the metaclass of the parent (Bar.__class__) will be. If Bar used a __metaclass__ attribute that created Bar with type() (and not type.__new__()), the subclasses will not inherit that behavior.
Can someone please explain this a little bit deeper? Would really appreciate some help here.@ppperry 2017-08-03 14:42:37
"type is actually its own metaclass. This is not something you could reproduce in pure Python, and is done by cheating a little bit at the implementation level." is not true.
__class__
is writable in Python, so one can create a subclass of type with a custom metaclass, and then set its class to itself.@Philip Stark 2017-08-16 09:17:39
@Deep: The actual metaclass of a class is specified in
.__class__
, whereas.__metaclass__
specifies which callable should be used to alter the class during creation. If for example.__metaclass__
contains a functionfoo_bar()
that usestype(x,y,z)
to alter the class, then you will have .__metaclass__ = foo_bar
which will not be inherited but.__class__
will betype
, because that's what was used to create the new altered class. Read this a few times. I am 99% sure I haven't made a mistake ;)@Mr_and_Mrs_D 2017-09-29 10:47:27
Now you wonder why the heck is it written in lowercase, and not Type?
- well because it's implemented in C - it's the same reason defaultdict is lowercase while OrderedDict (in python 2) is normal CamelCase@Shule 2017-11-08 08:59:31
It's a community wiki answer (so, those who commented with corrections/improvements might consider editing their comments into the answer, if they're sure they are correct).
@styrofoam fly 2018-01-19 15:21:21
Which parts of this answer is about
python2
and which aboutpythono3
?@René Nyffenegger 2018-04-03 12:40:38
If a metaclass is an object, does that object not also have a metaclass?
@Nearoo 2018-09-04 14:10:08
@RenéNyffenegger Yes, you can have a metaclass of a metaclass of a metaclass
@U9-Forward 2018-12-23 00:38:14
This is the best answer here, well-documented, well-explained deserve the number of upvotes.
@Thomas Wouters 2008-09-19 07:01:58
A metaclass is the class of a class. Like a class defines how an instance of the class behaves, a metaclass defines how a class behaves. A class is an instance of a metaclass.
While in Python you can use arbitrary callables for metaclasses (like Jerub shows), the more useful approach is actually to make it an actual class itself.
type
is the usual metaclass in Python. In case you're wondering, yes,type
is itself a class, and it is its own type. You won't be able to recreate something liketype
purely in Python, but Python cheats a little. To create your own metaclass in Python you really just want to subclasstype
.A metaclass is most commonly used as a class-factory. Like you create an instance of the class by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass. Combined with the normal
__init__
and__new__
methods, metaclasses therefore allow you to do 'extra things' when creating a class, like registering the new class with some registry, or even replace the class with something else entirely.When the
class
statement is executed, Python first executes the body of theclass
statement as a normal block of code. The resulting namespace (a dict) holds the attributes of the class-to-be. The metaclass is determined by looking at the baseclasses of the class-to-be (metaclasses are inherited), at the__metaclass__
attribute of the class-to-be (if any) or the__metaclass__
global variable. The metaclass is then called with the name, bases and attributes of the class to instantiate it.However, metaclasses actually define the type of a class, not just a factory for it, so you can do much more with them. You can, for instance, define normal methods on the metaclass. These metaclass-methods are like classmethods, in that they can be called on the class without an instance, but they are also not like classmethods in that they cannot be called on an instance of the class.
type.__subclasses__()
is an example of a method on thetype
metaclass. You can also define the normal 'magic' methods, like__add__
,__iter__
and__getattr__
, to implement or change how the class behaves.Here's an aggregated example of the bits and pieces:
@ppperry 2017-08-03 14:34:29
class A(type):pass<NEWLINE>class B(type,metaclass=A):pass<NEWLINE>b.__class__ = b
@Holle van 2018-09-18 23:24:10
ppperry he obviously meant you can't recreate type without using type itself as a metaclass. Which is fair enough to say.
@Ciasto piekarz 2018-11-29 00:59:15
Shouldn't unregister() be called by instance of Example class ?
@ARGeo 2018-09-15 12:41:20
In addition to the published answers I can say that a
metaclass
defines the behaviour for a class. So, you can explicitly set your metaclass. Whenever Python gets a keywordclass
then it starts searching for themetaclass
. If it's not found – the default metaclass type is used to create the class's object. Using the__metaclass__
attribute, you can setmetaclass
of your class:It'll produce the output like this:
And, of course, you can create your own
metaclass
to define the behaviour of any class that are created using your class.For doing that, your default
metaclass
type class must be inherited as this is the mainmetaclass
:The output will be:
@Michael Ekoka 2016-10-13 09:21:26
Role of a metaclass'
__call__()
method when creating a class instanceIf you've done Python programming for more than a few months you'll eventually stumble upon code that looks like this:
The latter is possible when you implement the
__call__()
magic method on the class.The
__call__()
method is invoked when an instance of a class is used as a callable. But as we've seen from previous answers a class itself is an instance of a metaclass, so when we use the class as a callable (i.e. when we create an instance of it) we're actually calling its metaclass'__call__()
method. At this point most Python programmers are a bit confused because they've been told that when creating an instance like thisinstance = SomeClass()
you're calling its__init__()
method. Some who've dug a bit deeper know that before__init__()
there's__new__()
. Well, today another layer of truth is being revealed, before__new__()
there's the metaclass'__call__()
.Let's study the method call chain from specifically the perspective of creating an instance of a class.
This is a metaclass that logs exactly the moment before an instance is created and the moment it's about to return it.
This is a class that uses that metaclass
And now let's create an instance of
Class_1
Observe that the code above doesn't actually do anything more than logging the tasks. Each method delegates the actual work to its parent's implementation, thus keeping the default behavior. Since
type
isMeta_1
's parent class (type
being the default parent metaclass) and considering the ordering sequence of the output above, we now have a clue as to what would be the pseudo implementation oftype.__call__()
:We can see that the metaclass'
__call__()
method is the one that's called first. It then delegates creation of the instance to the class's__new__()
method and initialization to the instance's__init__()
. It's also the one that ultimately returns the instance.From the above it stems that the metaclass'
__call__()
is also given the opportunity to decide whether or not a call toClass_1.__new__()
orClass_1.__init__()
will eventually be made. Over the course of its execution it could actually return an object that hasn't been touched by either of these methods. Take for example this approach to the singleton pattern:Let's observe what happens when repeatedly trying to create an object of type
Class_2
@Matthias Kestenholz 2008-09-19 06:32:58
I think the ONLamp introduction to metaclass programming is well written and gives a really good introduction to the topic despite being several years old already.
http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html (archived at https://web.archive.org/web/20080206005253/http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html)
In short: A class is a blueprint for the creation of an instance, a metaclass is a blueprint for the creation of a class. It can be easily seen that in Python classes need to be first-class objects too to enable this behavior.
I've never written one myself, but I think one of the nicest uses of metaclasses can be seen in the Django framework. The model classes use a metaclass approach to enable a declarative style of writing new models or form classes. While the metaclass is creating the class, all members get the possibility to customize the class itself.
The thing that's left to say is: If you don't know what metaclasses are, the probability that you will not need them is 99%.
@binbjz 2018-01-12 09:16:56
The type() function can return the type of an object or create a new type,
for example, we can create a Hi class with the type() function and do not need to use this way with class Hi(object):
In addition to using type() to create classes dynamically, you can control creation behavior of class and use metaclass.
According to the Python object model, the class is the object, so the class must be an instance of another certain class. By default, a Python class is instance of the type class. That is, type is metaclass of most of the built-in classes and metaclass of user-defined classes.
Magic will take effect when we passed keyword arguments in metaclass, it indicates the Python interpreter to create the CustomList through ListMetaclass. new (), at this point, we can modify the class definition, for example, and add a new method and then return the revised definition.
@Aaron Hall 2015-08-10 23:28:09
TLDR: A metaclass instantiates and defines behavior for a class just like a class instantiates and defines behavior for an instance.
Pseudocode:
The above should look familiar. Well, where does
Class
come from? It's an instance of a metaclass (also pseudocode):In real code, we can pass the default metaclass,
type
, everything we need to instantiate a class and we get a class:Putting it differently
A class is to an instance as a metaclass is to a class.
When we instantiate an object, we get an instance:
Likewise, when we define a class explicitly with the default metaclass,
type
, we instantiate it:Put another way, a class is an instance of a metaclass:
Put a third way, a metaclass is a class's class.
When you write a class definition and Python executes it, it uses a metaclass to instantiate the class object (which will, in turn, be used to instantiate instances of that class).
Just as we can use class definitions to change how custom object instances behave, we can use a metaclass class definition to change the way a class object behaves.
What can they be used for? From the docs:
Nevertheless, it is usually encouraged for users to avoid using metaclasses unless absolutely necessary.
You use a metaclass every time you create a class:
When you write a class definition, for example, like this,
You instantiate a class object.
It is the same as functionally calling
type
with the appropriate arguments and assigning the result to a variable of that name:Note, some things automatically get added to the
__dict__
, i.e., the namespace:The metaclass of the object we created, in both cases, is
type
.(A side-note on the contents of the class
__dict__
:__module__
is there because classes must know where they are defined, and__dict__
and__weakref__
are there because we don't define__slots__
- if we define__slots__
we'll save a bit of space in the instances, as we can disallow__dict__
and__weakref__
by excluding them. For example:... but I digress.)
We can extend
type
just like any other class definition:Here's the default
__repr__
of classes:One of the most valuable things we can do by default in writing a Python object is to provide it with a good
__repr__
. When we callhelp(repr)
we learn that there's a good test for a__repr__
that also requires a test for equality -obj == eval(repr(obj))
. The following simple implementation of__repr__
and__eq__
for class instances of our type class provides us with a demonstration that may improve on the default__repr__
of classes:So now when we create an object with this metaclass, the
__repr__
echoed on the command line provides a much less ugly sight than the default:With a nice
__repr__
defined for the class instance, we have a stronger ability to debug our code. However, much further checking witheval(repr(Class))
is unlikely (as functions would be rather impossible to eval from their default__repr__
's).An expected usage:
__prepare__
a namespaceIf, for example, we want to know in what order a class's methods are created in, we could provide an ordered dict as the namespace of the class. We would do this with
__prepare__
which returns the namespace dict for the class if it is implemented in Python 3:And usage:
And now we have a record of the order in which these methods (and other class attributes) were created:
Note, this example was adapted from the documentation - the new enum in the standard library does this.
So what we did was instantiate a metaclass by creating a class. We can also treat the metaclass as we would any other class. It has a method resolution order:
And it has approximately the correct
repr
(which we can no longer eval unless we can find a way to represent our functions.):@Mushahid Khan 2016-08-09 18:49:44
type
is actually ametaclass
-- a class that creates another classes. Mostmetaclass
are the subclasses oftype
. Themetaclass
receives thenew
class as its first argument and provide access to class object with details as mentioned below:Note:
Notice that the class was not instantiated at any time; the simple act of creating the class triggered execution of the
metaclass
.@Xingzhou Liu 2017-07-13 07:58:10
Python classes are themselves objects - as in instance - of their meta-class.
The default metaclass, which is applied when when you determine classes as:
meta class are used to apply some rule to an entire set of classes. For example, suppose you're building an ORM to access a database, and you want records from each table to be of a class mapped to that table (based on fields, business rules, etc..,), a possible use of metaclass is for instance, connection pool logic, which is share by all classes of record from all tables. Another use is logic to to support foreign keys, which involves multiple classes of records.
when you define metaclass, you subclass type, and can overrided the following magic methods to insert your logic.
anyhow, those two are the most commonly used hooks. metaclassing is powerful, and above is nowhere near and exhaustive list of uses for metaclassing.
@Jerub 2008-09-19 06:26:10
Note, this answer is for Python 2.x as it was written in 2008, metaclasses are slightly different in 3.x, see the comments.
Metaclasses are the secret sauce that make 'class' work. The default metaclass for a new style object is called 'type'.
Metaclasses take 3 args. 'name', 'bases' and 'dict'
Here is where the secret starts. Look for where name, bases and the dict come from in this example class definition.
Lets define a metaclass that will demonstrate how 'class:' calls it.
And now, an example that actually means something, this will automatically make the variables in the list "attributes" set on the class, and set to None.
Note that the magic behaviour that 'Initalised' gains by having the metaclass
init_attributes
is not passed onto a subclass of Initalised.Here is an even more concrete example, showing how you can subclass 'type' to make a metaclass that performs an action when the class is created. This is quite tricky:
@noɥʇʎԀʎzɐɹƆ 2016-12-27 02:21:01
The tl;dr version
The
type(obj)
function gets you the type of an object.The
type()
of a class is its metaclass.To use a metaclass:
@kindall 2011-06-21 16:30:26
Others have explained how metaclasses work and how they fit into the Python type system. Here's an example of what they can be used for. In a testing framework I wrote, I wanted to keep track of the order in which classes were defined, so that I could later instantiate them in this order. I found it easiest to do this using a metaclass.
Anything that's a subclass of
MyType
then gets a class attribute_order
that records the order in which the classes were defined.@Ethan Furman 2016-03-01 19:48:34
Python 3 update
There are (at this point) two key methods in a metaclass:
__prepare__
, and__new__
__prepare__
lets you supply a custom mapping (such as anOrderedDict
) to be used as the namespace while the class is being created. You must return an instance of whatever namespace you choose. If you don't implement__prepare__
a normaldict
is used.__new__
is responsible for the actual creation/modification of the final class.A bare-bones, do-nothing-extra metaclass would like:
A simple example:
Say you want some simple validation code to run on your attributes -- like it must always be an
int
or astr
. Without a metaclass, your class would look something like:As you can see, you have to repeat the name of the attribute twice. This makes typos possible along with irritating bugs.
A simple metaclass can address that problem:
This is what the metaclass would look like (not using
__prepare__
since it is not needed):A sample run of:
produces:
Note: This example is simple enough it could have also been accomplished with a class decorator, but presumably an actual metaclass would be doing much more.
The 'ValidateType' class for reference:
@Nickpick 2017-11-11 13:01:29
In the metaclass example I get
NameError: name 'ValidateType' is not defined
. Any suggestions how to best fix this? I'm using python 2@Craig 2014-02-24 21:20:49
A metaclass is a class that tells how (some) other class should be created.
This is a case where I saw metaclass as a solution to my problem: I had a really complicated problem, that probably could have been solved differently, but I chose to solve it using a metaclass. Because of the complexity, it is one of the few modules I have written where the comments in the module surpass the amount of code that has been written. Here it is...
@Antti Rasinen 2008-09-19 06:45:40
One use for metaclasses is adding new properties and methods to an instance automatically.
For example, if you look at Django models, their definition looks a bit confusing. It looks as if you are only defining class properties:
However, at runtime the Person objects are filled with all sorts of useful methods. See the source for some amazing metaclassery.
@trixn 2017-01-27 23:24:42
Isn't the use of meta classes adding new properties and methods to a class and not an instance? As far as i understood it the meta class alters the class itself and as a result the instances can be constructed differently by the altered class. Could be a bit misleading to people who try to get the nature of a meta class. Having useful methods on instances can be achieved by normal inherence. The reference to Django code as an example is good, though.