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
--
http://mail.python.org/mailman/listinfo/python-list