Firstly, is there a reason why __prepare__
is a class method? Definition does not use metacls - is it just a convention?
As pointed out in the comments, when __prepare__
is called, the class itself has not yet been created. This means that if this is a regular method (with self
as the first parameter) - there will be no value in this call to become self
.
And this makes sense, because the fact that __prepare__
is to return an object of type dict, which will be used instead of the usual dict in parsing the body of the class, is therefore not dependent on the class being created at all.
If, as mentioned in the comments, it was a staticmethod
(which means that it will not receive the first metacls
parameter), then __prepare__
will not be able to access any other metaclass methods - this is not necessarily a limitation.
And yes, just like self
, metacls
in this case is just a convention - the usual Python identifier. (Note that when class methods are used in regular classes, the first parameter is usually indicated by cls
instead of metacls
.)
Secondly, when I try to execute this code, __module__
ends in MyClass.member_names before method1
and method2
, which seems to contradict the comments that claim that method1
is the first element. Why does this special attribute get on the list while others are not? Are there others that might surprise me (other than __doc__
if the class has a docstring, and any one I define explicitly)?
Probably because the special __module__
element for classes was thought up after they thought of the __prepare__
method for metaclasses. (I could not check on Google for the PEP defining __module__
, but I would say that it is.)
And no, there is no guarantee that future versions of Python will not add a few more magic attributes to classes that may appear in front of your explicit class members in the dictionary.
But with metaclasses, you have complete control - you can simply set up your object of type dict ( member_table
in your code) to not count any attributes starting with "__" - for example. Or even not adding to the final class instance at all (at the risk of your classes defining this method without working with certain Python functions).
Finally, this implementation does not extract member elements from base classes. If I want to achieve this, is there something wrong with the next change to __prepare__
?
Reading it, I see nothing wrong with your proposed implementation, but of course you will have to test it.
Update (2013-06-30): this issue is being actively discussed in the list of Python developers, and it looks like from Python 3.4, all classes will be ordered by default, without the need to use a metaclass or __prepare__
for order only