__autoinit__ (Was: Proposal: reducing self.x=x; self.y=y; self.z=z boilerplate code)
Kay Schluehr
kay.schluehr at gmx.net
Sat Jul 9 08:39:34 EDT 2005
Ralf W. Grosse-Kunstleve schrieb:
> My initial proposal
> (http://cci.lbl.gov/~rwgk/python/adopt_init_args_2005_07_02.html) didn't
> exactly get a warm welcome...
Well ... yes ;)
Ralf, if you want to modify the class instantiation behaviour you
should have a look on metaclasses. That's what they are for. It is not
a particular good idea to integrate a new method into the object base
class for each accidental idea and write a PEP for it.
I provide you an example which is actually your use case. It doesn't
change the class hierarchy : the metaclass semantics is not "is a" as
for inheritance but "customizes" as one would expect also for
decorators.
class autoattr(type):
'''
The autoattr metaclass is used to extract auto_xxx parameters from
the argument-tuple or the keyword arguments of an object
constructor __init__
and create object attributes mit name xxx and the value of auto_xxx
passed
into __init__
'''
def __init__(cls,name, bases, dct):
super(autoattr,cls).__init__(name,bases,dct)
old_init = cls.__init__
defaults = cls.__init__.im_func.func_defaults
varnames = cls.__init__.im_func.func_code.co_varnames[1:]
def new_init(self,*args,**kwd):
for var,default in zip(varnames[-len(defaults):],defaults):
if var.startswith("auto_"):
self.__dict__[var[5:]] = default
for var,arg in zip(varnames,args):
if var.startswith("auto_"):
self.__dict__[var[5:]] = arg
for (key,val) in kwd.items():
if key.startswith("auto_"):
self.__dict__[key[5:]] = val
old_init(self,*args,**kwd)
cls.__init__ = new_init
class app:
__metaclass__ = autoattr
def __init__(self, auto_x, y, auto_z = 9):
pass
>>> a = app(2,5)
>>> a.x
2
>>> a.z
9
>>> a.y
-> AttributeError
Kay
More information about the Python-list
mailing list