another question on metaclasses
Michele Simionato
mis6 at pitt.edu
Tue Dec 10 14:01:17 EST 2002
I am trying to understand metaclasses and this is my first program
using them. I post it in order to have some feedback, since I don't feel
completely confident with the subject yet. I would like to know if what I
am doing is correct and if there are better ways to accomplish the same.
Here is the motivation for the script. It is very common to have a class
B with some __init__ method which is extended in a derived class C:
class B(object):
def __init__(self,*args,**kw):
print "This is B.__init__"
class C(B):
def __init__(self,*args,**kw):
B.__init__(self,*args,**kw)
print "This is C.__init__"
Notice that the B.__init__ method has to be called explicitly. In general
this is fine, but in some cases it would be handy to have B.__init__ called
automatically. To perform this, I used metaclasses:
-------------- begin MetaInit.py -----------------------
class MetaInit(type):
"""If cls inherits from bases, and cls.__metaclass__==MetaInit, then
cls.__init__ is extended to call super(cls).__init__ ."""
def __init__(cls,name,bases,dict):
child_init=cls.__init__ #makes a copy ?
def double_init(self,*args,**kw):
"Both the super and the child __init__ are called"
super(cls,self).__init__(self,*args,**kw)
child_init(self,*args,**kw)
setattr(cls,'__init__',double_init)
class Autoinit(object):
"""Autoinit should be thought as a mixin class. Classes derived from
Autoinit automagically call their super __init__ methods according to
the MRO. The magic works because Autoinit-derived classes inherit the
Autoinit metaclass MetaInit. Notice that Autounit itself inherit its
__init__ method from object, which does nothing."""
__metaclass__ = MetaInit
class B(Autoinit):
def __init__(self,*args,**kw):
print "This is B.__init__"
class C(Autoinit):
def __init__(self,*args,**kw):
print "This is C.__init__"
class D(B,C):
def __init__(self,*args,**kw):
print "This is D.__init__"
d=D()
------- end MetaInit.py -------
The output of this program is
This is C.__init__
This is B.__init__
This is D.__init__
i.e. what I want. Nevertheless, I wonder if there are cases where this script
could break down, then I ask the Python gurus for comments and feedback.
TIA,
--
Michele Simionato - Dept. of Physics and Astronomy
210 Allen Hall Pittsburgh PA 15260 U.S.A.
Phone: 001-412-624-9041 Fax: 001-412-624-9163
Home-page: http://www.phyast.pitt.edu/~micheles/
More information about the Python-list
mailing list