reducing self.x=x; self.y=y; self.z=z boilerplate code

Josiah Carlson wrote:
Now, don't get me wrong, definining __slots__ can be a pain in the tookus, but with a proper metaclass, that metaclass can define the __slots__ attribute based on the argument list for __init__().
There you go.
Where? The meta-class idea sounds interesting. Could you work it out?
A syntax change is wholly unnecessary.
I wonder why everybody gets so agitated about a syntax enhancement proposal. I am not proposing a syntax change! I know enhancing the syntax is work, but shouldn't a syntax leading to less code clutter be the higher value? IMO a long-term gain counts for much more than avoiding a one-time investment implementing a useful feature. Take, for example, the syntax enhancement supporting "import foo as bar". I could just as easily write: import foo bar = foo del foo "A syntax change is wholly unnecessary." Why was it important enough anyway? It was a good enhancement because it is clearly more expressive and reduces clutter. In my experience the self.x=x; self.y=y etc. problem arises much more often than the problem solved by "import foo as bar". IMO a *built-in* solution is much more important in practice. Why does everybody have to reinvent the adopt_init_args/initialize wheel, or have to sheepishly type self.x=x...? I am not wedded to the .x idea, but counter-proposals should be at least approximately as powerful as what I propose.
class grouping: def __init__(self, _x, _y, _z): initialize(self, locals())
The "_x" alternative looks interesting but is problematic: it doesn't have a special meaning so far, but it is also not a syntax error. You are also not getting rid of the odd (from a learner's viewpoint) requirement to stick in "locals()". Remember where Python comes from: it goes back to a teaching language, enabling non-geeks to write programs. "initialize(self, locals())" doesn't fit that bill, especially if you have to import initialize first. In contrast def __init__(self, .x, .y, .z): ^^^^^^^^ almost looks like ^^^^^^ self.x and should therefore be easy to learn and remember. I'd also be happy with def __init__(self, self.x, self.y, self.z): which wouldn't be too different from unpacking tuples (and is currently a syntax error). However, remember, elegance = power/length. .x above has the same power as self.x, but is shorter, therefore more elegant. :) Hoping-that-this-leads-to-some-consensus-for-a-*built-in*-solution-ly yours, Ralf

Ralf W. Grosse-Kunstleve wrote:
I know enhancing the syntax is work, but shouldn't a syntax leading to less code clutter be the higher value? IMO a long-term gain counts for much more than avoiding a one-time investment implementing a useful feature. Take, for example, the syntax enhancement supporting "import foo as bar". I could just as easily write:
import foo bar = foo del foo
"A syntax change is wholly unnecessary." Why was it important enough anyway? It was a good enhancement because it is clearly more expressive and reduces clutter.
In my experience the self.x=x; self.y=y etc. problem arises much more often than the problem solved by "import foo as bar". IMO a *built-in* solution is much more important in practice. Why does everybody have to reinvent the adopt_init_args/initialize wheel, or have to sheepishly type self.x=x...?
Actually, this reminds me of a recent suggestion (from AMK?) about being able to get at both the packed and unpacked form of an argument via: def f(arg as (a, b, c)): print arg print c, b, a Then f([1, 2, 3]) would print: [1, 2, 3] 3 2 1 If the right hand side of 'as' permitted the same forms as are going to be permitted for the 'as' clause in 'with' statements, then Ralf's situation could be handled via: def __init__(self as s, x as s.x, y as s.y, z as s.z): pass Essentially, it allows arguments to be given two names - a public name (before the 'as', used for keyword arguments), and a private name (after the 'as', not used for keyword arguments, allows easy shorthand aliasing of self, unpacking of tuple arguments, and easy assignment of instance variables). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com

Nick Coghlan wrote: [...]
If the right hand side of 'as' permitted the same forms as are going to be permitted for the 'as' clause in 'with' statements, then Ralf's situation could be handled via:
def __init__(self as s, x as s.x, y as s.y, z as s.z): pass
Essentially, it allows arguments to be given two names - a public name (before the 'as', used for keyword arguments), and a private name (after the 'as', not used for keyword arguments, allows easy shorthand aliasing of self, unpacking of tuple arguments, and easy assignment of instance variables).
There once was a suggestion like this on c.l.py, expanding this to other statements, like: if re.match('a.*b', text) as m: # do something What has become of this? It seems to be a wanted feature, and while I concur that classic 'C-style' assignment-as-expression is undesirable (because of the =/== bug-source), this would be a way, wouldn't it? Reinhold -- Mail address is perfectly valid!

"Ralf W. Grosse-Kunstleve" <rwgk@cci.lbl.gov> wrote:
Josiah Carlson wrote:
Now, don't get me wrong, definining __slots__ can be a pain in the tookus, but with a proper metaclass, that metaclass can define the __slots__ attribute based on the argument list for __init__().
There you go.
Where? The meta-class idea sounds interesting. Could you work it out?
I had assumed that you were a 'go-getter', and that you would want to figure it out yourself. Apparently I was wrong. Being that I don't use metaclasses (I don't need the functionality), I had to spend 10 minutes learning about them, and 5 minutes implementing the following. class AutoSlots(type): def __init__(cls, name, bases, dct): slots = dict.fromkeys(dct.get('__slots__', [])) if '__init__' in dct: init = dct['__init__'] ifvn = init.func_code.co_varnames for i in xrange(init.func_code.co_argcount): x = ifvn[i] if x[:1] == '_'and x[1:] not in slots: slots[x[1:]] = None if slots: dct['__slots__'] = slots.keys() super(AutoSlots, cls).__init__(name, bases, dct) def InitSlots(ob, args): for k, v in args.items(): if k[:1] == '_': setattr(ob,k[1:],v) class Foo(object): __metaclass__ = AutoSlots def __init__(self, a, b, _x, _y=None): InitSlots(self, locals())
foo = Foo(1,2,3) vars(foo) {'y': None, 'x': 3}
A syntax change is wholly unnecessary.
I wonder why everybody gets so agitated about a syntax enhancement proposal. I am not proposing a syntax change!
Yes you are. Any thing that changes syntax, necessarily is a syntax change. People get "agitated" because with every syntax addition, that is just another syntax that a newbie may need to learn in order to understand some block of code. Further, for those of us who try to teach about it, it is just one more little nit that students ask about. Considering that EVERYTHING you want is possible with 17 lines of support code (which can be tossed into site and assigned to __builtins__), and 2 lines of boilerplate (which can be made into one metaclass line if you are willing to do a bit more work), a syntax change is foolishness.
I know enhancing the syntax is work, but shouldn't a syntax leading to less code clutter be the higher value?
Why bother if the non-syntax-change goes 99% of the way? I've further pushed myself to -10 for any syntax change offering during my implementation of AutoSlots. - Josiah

"Ralf W. Grosse-Kunstleve" <rwgk@cci.lbl.gov> wrote in message news:200507020319.j623JAUu311991@boa.lbl.gov...
I'd also be happy with
def __init__(self, self.x, self.y, self.z):
which wouldn't be too different from unpacking tuples
If you are willing to require that the args be passed as a tuple (extra pair of parens) I believe you could do def __init__(s, args): s.x, s.y, s.z = args This even checks for correct number of actual args. I believe part of your underlying point is that you do not (usually) in this type of situation really need or want the args to be separately named locals since you just want to attach them to the instance. (Way too late, may have made an error.) Terry J. Reedy
participants (5)
-
Josiah Carlson
-
Nick Coghlan
-
Ralf W. Grosse-Kunstleve
-
Reinhold Birkenfeld
-
Terry Reedy