Metaclasses Demystified

Boris Arloff boris.arloff at yahoo.com
Thu Jun 11 00:25:25 EDT 2009


Hi,

I have been studying python metaclasses for a few days now and I believe that slowly but surely I am grasping the subject.  The best article I have found on this is "Metaclass Demystified", by J. LaCour, Python Magazine, July 2008 (http://cleverdevil.org/computing/78/).

I replicated the article's Enforcer example in python 3.0 and while I understand its functionality I have trouble understanding the behind the scene behavior.  I created a file containing classes Field, EnforcerMeta, Enforcer and Person, in this order.  The file is then imported with the python ide.  To save space I do not replicate the code here since it is available at the above link.  The following describes events when the file is imported and I hope that someone may offer clarifications on my comments/questions:

1.  First, the EnforcerMeta's __init__ method executes at import and its namespace (ns) shows to contain '__module__' and '__setattr__' attributes.  I did not expect __init__ to execute at this point since there has not been an instantiation yet.  Does this happens because we inherit from type and the python engine instantiates metaclasses?

2. Second, the for loop of EnforcerMeta checks the two attributes to be instances of class Field to add them in the _fields dict.  Since Field has not been instantiated with these attributes, they are not added to the dict.  No problem here, this is expected.

3.  Then,  class Person declaration is encountered with two class variables 'name' and 'age' which are defined as Field(str) and Field(int), respectively.  Hence, we have two instances of class Field each with a corresponding instance ftype attribute.  No problem with this either, as expected.

4.  The next events are somewhat puzzling however.  Class EnforcerMeta's __init__ executes again with a ns containing attributes 'age', 'name', and '__module__' .  The for loop executes and this time 'age' and 'name' are added to the _fields dict, while '__module__' understandably is not added.  However,

4.a.  What happened to attribute '__setattr__'?  Why is it not present anymore in the ns?

4.b.  What kind of magic makes EnforcerMeta to instantiate this second time?  I did not expect this to happen at all.  I can try to rationalize its instance in step 1 above, but I cannot come up with any such explanation for this second instantiation.  Is it because Enforcer doing this by inheriting the metaclass, which in turn is inherited by class Person?

I tested the code by creating an instance of class Person and then assigning values to its attributes name and age.  The code works correctly as per the article's example.

Any clarifications to the above questions will be greatly appreciated.  I am trying to get versed with the black magic of metaclasses and hope to use them in a personal academic research whereby I will try to create class objects on the fly at runtime out of nothing; or almost nothing.

I can attach my code if necessary, but as indicated it is identical to LaCour's in the article with the necessary syntax changes for python 3.0.

Thanks 
Boris




      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090610/42527d74/attachment.html>


More information about the Python-list mailing list