Hi Michael, Thanks for taking a careful look, and thanks for the balanced analysis!
Michael Chermside wrote: > A better name would help with this. OK. After getting so many beatings I'd agree to anything. :) > The need for locals() is unavoidable. It is in fact not unavoidable. I pointed to my prototype before, but sorry, it is probably confusing that my two prototypes have the same name. They just live in different modules. For easier access I inline the second version that works without having to write "locals()" (from libtbx.introspection): def frame_object(frames_back=0): try: raise Exception except: t = sys.exc_info()[2] f = t.tb_frame for i in xrange(frames_back+1): if (f.f_back is None): break f = f.f_back return f def adopt_init_args(exclusions=[], prefix="", frames_back=0): frame = frame_object(frames_back=frames_back+1) varnames = frame.f_code.co_varnames exclusions.append(varnames[0]) # self init_locals = frame.f_locals self = init_locals[varnames[0]] for varname in varnames: if (varname not in exclusions): setattr(self, prefix+varname, init_locals[varname]) if ("__init__varnames__" not in exclusions): setattr(self, "__init__varnames__", varnames) I am sure this can be improved and stripped down to the essentials. E.g. I wasn't aware of sys._getframe() as just pointed out by Thomas Heller (thanks!). To me this just shows that finding the optimal solution is not entirely trivial and should therefore be done "right" once and forever in a community effort. Ultimately I hope it will be done in C for speed. That's the main goal of my proposal. > But for REAL beginners, I wouldn't even bother... writing out "self.x = x" > is useful for beginners since it helps make it very clear and concrete to > them just what is happening. In my experience real Python beginners grow very skeptical when I make them type highly redundant code. Many are just waiting for excuses not to learn Python and to continue with whatever they know (in my field FORTRAN!). Even class point: def __init__(self, x, y): self.x = x self.y = y makes for wrinkled noses. If I didn't use my home-grown adopt_init_args() function in the real-world code pointed out earlier the FORTRAN faction probably wouldn't stop making fun of me ("Why doesn't he use COMMON blocks?"). > > - In some cases the ``adopt_init_args()`` overhead was found to > > introduce a significant performance penalty (in particular the > > enhanced version discussed below). > > Again... a different code will help here. And if execution speed is > REALLY a concern, then you can just write it out the long way! Why should anyone have to think about technicalities like this? If we had an efficient C version included with Python nobody would have to. One solution works for everything. > The VERY simple, VERY straightforward, VERY common behavior of > "store all the arguments as like-named attributes of self" is > worth having a standard idiom (and *perhaps* a built-in). But > odd special cases like skipping some arguments... that calls > for writing the whole thing out. I'm firmly -1 on any proposal > to support skipping arguments. OK. "del x" is almost as good. I was motivated by speed concerns (first adding x to self.__dict__, then removing it again), but it is most likely a very minor issue, and my prototype with the repeated list lookup may even backfire anyway. > > When ``__slots__`` are used (cool feature!) the boilerplate problem > > becomes even worse:: > > > > class grouping: > > > > __slots__ = ["keep_this", "and_this", "but_this_again"] > > > > def __init__(self, keep_this, and_this, but_not_this, but_this_again): > > self.keep_this = keep_this > > self.and_this = and_this > > self.but_this_again = but_this_again > > # real code, finally > > > > Each variable name appears four times! > > ** NO! ** > > __slots__ is *NOT* to be used except for those times when you NEED > the performance advantages (mostly memory use). The simple rule is > that you should *NEVER* use __slots__ (if you are in a situation > where you *do* need it, then you'll know enough to understand why > this advice doesn't apply to you). There should NOT be any support > for auto-setting __slots__ *anywhere* in the standard library, > because it would make it FAR too tempting for people to mis-use > __slots__. > > Besides, a metaclass would be a better solution, and it can be done > today with no modifications to Python. I am very puzzled to see the huge ** NO! **. If __slots__ improve performance and reduce memory, what is wrong with using this feature? I clearly was in situations where I needed __slots__, but I still don't know what the dangers could be. Could you please explain a little more? > All in all, I think there's SOME merit to this idea, in that this > is a common enough practice that it might be nice to make it easy > to type (and read). But your proposal entangles the good idea with > several ideas I rather dislike, and on the whole I think it sounds > rather dangerous. I am OK to strip down the proposal to concentrate solely on an optimal, fast, C-coded built-in function. That alone would be a major step forward, with a life-changing potential similar to that of zip, enumerate, or inplace operators (+=, *=, etc.). (I guess I am showing my age.) I was also considering working in Josiah Carlson's metaclass solution (http://mail.python.org/pipermail/python-list/2005-July/288349.html) to the __slots__ problem, but after reading your message I am not so sure anymore... Cheers, Ralf ____________________________________________________ Yahoo! Sports Rekindle the Rivalries. Sign up for Fantasy Football http://football.fantasysports.yahoo.com -- http://mail.python.org/mailman/listinfo/python-list