Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
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! ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Ralf W. Grosse-Kunstleve [EMAIL PROTECTED] 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 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Ralf W. Grosse-Kunstleve [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] 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 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Aahz wrote: This is off-topic for python-dev. Please take it to comp.lang.python. (It's not immediately obvious that this is off-topic, I know, but please take my word for it.) Done: http://mail.python.org/pipermail/python-list/2005-July/288292.html Sorry for creating so much noise here. Cheers, Ralf ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Hi, I often find myself writing: class grouping: def __init__(self, x, y, z): self.x = x self.y = y self.z = z I hate it, and every time I show this to a Python newcomer I get that skeptic look. How about this for a change? class grouping: def __init__(self, .x, .y, .z): pass This is supposed to work the same way as: def __init__(self, x, y, z): self.x = x del x self.y = y del y self.z = z del z Currently the .x syntax leads to: def __init__(self, .x, .y, .z): ^ SyntaxError: invalid syntax I.e. it seems to me that there shouldn't be any backward compatibility issues. I'll write a PEP if I hear a few voices of support. (Otherwise I'll stick to my adopt_init_args workaround: http://phenix-online.org/cctbx_sources/libtbx/libtbx/introspection.py which does a similar job but doesn't look as elegant and is also quite inefficient). Cheers, Ralf ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
At 03:59 PM 7/1/2005 -0700, Ralf W. Grosse-Kunstleve wrote: Hi, I often find myself writing: class grouping: def __init__(self, x, y, z): self.x = x self.y = y self.z = z I hate it, and every time I show this to a Python newcomer I get that skeptic look. How about this for a change? class grouping: def __init__(self, .x, .y, .z): pass This extends to any number of arguments: class grouping: def __init__(self, x, y, z): self.__dict__.update(locals()) del self.self Or if you prefer a more generic approach: def initialize(ob, args): if 'self' in args: del args['self'] for k, v in args.items(): setattr(ob,k,v) class grouping: def __init__(self, x, y, z): initialize(self, locals()) There's really no need for special syntax here, if your goal is simply to reduce boilerplate. I'll write a PEP if I hear a few voices of support. -1; there are lots of good solutions for this. For me, I usually have a base class with something like this: def __init__(self, **kw): for k, v in kw.items(): if not hasattr(self.__class__, k): raise TypeError(%s has no %r attribute % (self.__class__,k)) else: setattr(self,k,v) And then subclasses define their attributes and defaults using class attributes, properties, or other descriptors. (Otherwise I'll stick to my adopt_init_args workaround: http://phenix-online.org/cctbx_sources/libtbx/libtbx/introspection.py which does a similar job but doesn't look as elegant and is also quite inefficient). There are more efficient solutions, especially __dict__.update(). ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
On Fri, 01 Jul 2005 19:22:20 -0400, Phillip J. Eby [EMAIL PROTECTED] wrote: At 03:59 PM 7/1/2005 -0700, Ralf W. Grosse-Kunstleve wrote: [snip] This extends to any number of arguments: class grouping: def __init__(self, x, y, z): self.__dict__.update(locals()) del self.self If you use vars(self).update(locals()), it even looks halfway pleasant ;) I'm not sure what python-dev's current opinion of vars(obj) is though (I'm hoping someone'll tell me). Of course, both of these fall over for __slots__'ful classes. It'd be nice if there were a general way to deal with attributes of an instance, regardless of the implementation details of its memory layout. Jp ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
I am happy to see that others agree we need something better than self.x=x; self.y=y; self.z=z. Phillip J. Eby wrote: class grouping: def __init__(self, x, y, z): initialize(self, locals()) Been there (older code): http://phenix-online.org/cctbx_sources/scitbx/scitbx/python_utils/misc.py I don't like it because - I do have to remember how to import adopt_init_args/initialize. - I also have to remember the locals() part (unpythonic boilerplate again). - I get both self.x and 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). - It is sure to be less efficient than the .x support I propose. I'd be happy if - adopt_init_args/initialize became a (efficiently implemented) Python built-in. - and the locals() part is not needed. However, IMO the .x solution is still far better because I often want to do something like this: class grouping: def __init__(self, .keep_this, .and_this, but_not_this, .but_this_again): pass With the adopt_init_args/initialize solution you'd have to write: class grouping: def __init__(self, keep_this, and_this, but_not_this, but_this_again): initialize(self, locals(), exclude=[but_not_this]) Unpythonic boilerplate again (the but_not_this duplication). Cheers, Ralf ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Jp Calderone wrote: If you use vars(self).update(locals()), it even looks halfway pleasant ;) I'm not sure what python-dev's current opinion of vars(obj) is though (I'm hoping someone'll tell me). Of course, both of these fall over for __slots__'ful classes. It'd be nice if there were a general way to deal with attributes of an instance, regardless of the implementation details of its memory layout. That's where PJE's more generic approach comes in: def initialize(ob, args, excluded=['self']): for k in excluded: if k in args: del args[k] for k, v in args.items(): setattr(ob,k,v) class grouping: def __init__(self, x, y, z): initialize(self, locals()) Or, one could have a look at the 'namespace' module, which came out of the last pre-PEP covering this kind of area: http://namespace.python-hosting.com/ 'Record' is particularly interesting from an auto-initialisation point of view (the class attributes define the expected instance attributes). Although I may be a little biased, since I wrote that class. . . Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.blogspot.com ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Jp Calderone wrote: If you use vars(self).update(locals()), it even looks halfway pleasant ;) I'm not sure what python-dev's current opinion of vars(obj) is though (I'm hoping someone'll tell me). http://docs.python.org/lib/built-in-funcs.html#l2h-76 is pretty clear: vars([object]) Without arguments, return a dictionary corresponding to the current local symbol table. With a module, class or class instance object as argument (or anything else that has a __dict__ attribute), returns a dictionary corresponding to the object's symbol table. The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined. Of course, both of these fall over for __slots__'ful classes. It'd be nice if there were a general way to deal with attributes of an instance, regardless of the implementation details of its memory layout. I agree. Ideally I'd like this class grouping: __slots__ = True def __init__(self, .x, .y, .z): pass to be equivalent to: class grouping: __slots__ = [x, y, z] def __init__(self, x, y, z): self.x = x del x self.y = y del y self.z = z del z Cheers, Ralf ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
Nick Coghlan [EMAIL PROTECTED] wrote: Jp Calderone wrote: If you use vars(self).update(locals()), it even looks halfway pleasant ;) I'm not sure what python-dev's current opinion of vars(obj) is though (I'm hoping someone'll tell me). Of course, both of these fall over for __slots__'ful classes. It'd be nice if there were a general way to deal with attributes of an instance, regardless of the implementation details of its memory layout. That's where PJE's more generic approach comes in: def initialize(ob, args, excluded=['self']): for k in excluded: if k in args: del args[k] for k, v in args.items(): setattr(ob,k,v) class grouping: def __init__(self, x, y, z): initialize(self, locals()) I'm with everyone else on this, -1 on .x syntax. As provided in the 6 line function above, everything desired is available. You want something that you don't need to use the excluded argument for, but still has the same stench as what Ralf originally offered? def initialize(ob, args): for k, v in args.items(): if k[:1] == '_': setattr(ob,k[1:],v) class grouping: def __init__(self, _x, _y, _z): initialize(self, locals()) 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. A syntax change is wholly unnecessary. - Josiah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
On Fri, Jul 01, 2005, 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 I hate it, and every time I show this to a Python newcomer I get that skeptic look. How about this for a change? class grouping: def __init__(self, .x, .y, .z): pass This is off-topic for python-dev. Please take it to comp.lang.python. (It's not immediately obvious that this is off-topic, I know, but please take my word for it.) -- Aahz ([EMAIL PROTECTED]) * http://www.pythoncraft.com/ f u cn rd ths, u cn gt a gd jb n nx prgrmmng. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code
On Saturday 02 July 2005 08:59, Ralf W. Grosse-Kunstleve wrote: I hate it, and every time I show this to a Python newcomer I get that skeptic look. How about this for a change? class grouping: def __init__(self, .x, .y, .z): pass -1. Syntax should not look like grit on my monitor. Anthony -- Anthony Baxter [EMAIL PROTECTED] It's never too late to have a happy childhood. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com