Re: [Python-Dev] reducing self.x=x; self.y=y; self.z=z boilerplate code

2005-07-02 Thread Reinhold Birkenfeld
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

2005-07-02 Thread Josiah Carlson

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

2005-07-02 Thread Terry Reedy

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

2005-07-02 Thread Ralf W. Grosse-Kunstleve
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

2005-07-01 Thread Ralf W. Grosse-Kunstleve
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

2005-07-01 Thread Phillip J. Eby
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

2005-07-01 Thread Jp Calderone
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

2005-07-01 Thread Ralf W. Grosse-Kunstleve
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

2005-07-01 Thread Nick Coghlan
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

2005-07-01 Thread Ralf W. Grosse-Kunstleve
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

2005-07-01 Thread Josiah Carlson

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

2005-07-01 Thread Aahz
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

2005-07-01 Thread Anthony Baxter
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