<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Hi,<br><br>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/).<br><br>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:<br><br>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?<br><br>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.<br><br>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.<br><br>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,<br><br>4.a. What happened to attribute '__setattr__'? Why is it not present anymore in the ns?<br><br>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?<br><br>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.<br><br>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.<br><br>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.<br><br>Thanks <br>Boris<br><br></td></tr></table><br>