Ralf W. Grosse-Kunstleve wrote: > I often find myself writing:: > > class grouping: > > def __init__(self, x, y, z): > self.x = x > self.y = y > self.z = z > # real code, finally > > This becomes a serious nuisance in complex applications with long > argument lists
Yes... indeed it does. This is so common that there is a standard idiom for handling it: def __init__(self, x, y, z): self.__dict__.update(locals()) sometimes with modifications to avoid setting self.self. > Therefore I propose that Python includes > built-in support for reducing the ``self.x=x`` clutter. If all you were proposing was a built-in function to make this particular idiom clearer and more reliable, then I think I'd back such a feature because the need is SO common. However, the suggestion you actually make: > def __init__(self, .x, .y, .z): > # real code right here is far too broad and introduces new syntax unnecessarily. You yourself are using a helper function (although I belive it could be done more easily than you did it): > I am actually using a simple trick:: > > adopt_init_args(self, locals()) To which you raise the following objections: > - The solution doesn't come with Python -> everybody has to reinvent. Good point. Particularly since people won't think of all the special cases (eg: classes with __slots__ defined). > - People are reluctant to use the trick since scripts become > dependent on a non-standard feature. > - It is difficult to remember which ``import`` to use for > ``adopt_init_args`` (since everybody has a local version/variety). If the implementation is only 3-4 lines long (and a simpler implementation can be), then is can simply be included inline with every script that needs to use it. > - The ``adopt_init_args(self, locals())`` incantation is hard to > remember and difficult to explain to new-comers. A better name would help with this. The need for locals() is unavoidable. 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. > - Inside the ``__init__()`` method, the same object has two names, > e.g. ``x`` and ``self.x``. This lead to subtle bugs a few times > when I accidentally assigned to ``x`` instead of ``self.x`` or vice > versa in the wrong place (the bugs are typically introduced while > refactoring). Hmm... I've never had that problem, myself. > - 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! > - Remember where Python comes from: it goes back to a teaching > language, enabling mere mortals to embrace programming. > ``adopt_init_args(self, locals())`` definitely doesn't live up > to this heritage. No, but "self.x = x" does. It's only when you have lots of variables or very long names that this approach becomes unwieldy. > My minimal proposal is to add an enhanced version of ``adopt_init_args()`` > as a standard Python built-in function (actual name secondary!):: I'd alter the name and the implementation, but the basic idea seems sound to me. > However, there is another problem not mentioned before: > It is cumbersome to disable adoption of selected variables. 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. > 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. . . . 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. -- Michael Chermside -- http://mail.python.org/mailman/listinfo/python-list