Вот, пожалуйста, в простейшей форме:
def lazy_init(*param_names):
def ret(old_init):
def __init__(self, *args, **kwargs):
if len(args) > len(param_names):
raise TypeError("Too many arguments")
for k in kwargs:
if k not in param_names:
raise TypeError("Arg %r unexpected" % k)
for par, arg in zip(param_names, args):
setattr(self, par, arg)
for par, arg in kwargs.items():
setattr(self, par, arg)
old_init(*args, **kwargs)
return __init__
#
return ret
class Q(object):
@lazy_init("a", "b")
def __init__(self, *args, **kwargs):
print "Original init"
>>> q = Q(1, 2)
Original init
>>> q.a, q.b
(1, 2)
Подумайте над созданием декоратора класса, который бы охватил __str__
.