[Python-ideas] New syntax for 'dynamic' attribute access

Greg Falcon veloso at verylowsodium.com
Fri Feb 9 17:15:23 CET 2007


On 2/9/07, Ben North <ben at redfrontdoor.org> wrote:
> Hi,
>
> I'd like to describe an addition I made to Python syntax which allows
> easier access to attributes where the attribute name is only known at
> run-time.  For example:
>
>         setattr(self, method_name, getattr(self.metadata, method_name))
>
> from Lib/distutils/dist.py could be rewritten
>
>         self.(method_name) = self.metadata.(method_name)

Wow!  I have to say this is a compelling idea.  The syntax is a bit
foreign looking, but
  obj.(expr) += 1
is just such a huge win over
  setattr(obj, expr, getattr(obj, expr) + 1)
that I feel like I could learn to like it anyway.

So a few thoughts from the peanut gallery.

The problem with the syntax is that it looks a good bit like a
function call.  The dot can get easily lost when rendered in a
proportional font.  Because of this, I keep wanting to write the
punctuation as something else, possibly .* , but I think that's my C++
bias shining through.  (And as you point, your syntax does have the
precedent of MATLAB.)

>     This PEP describes a new syntax for dynamic attribute access ---
>     "x.(expr)" --- with examples given in the Abstract above.  The new
>     syntax also allows the provision of a default value in the "get"
>     case, as in:
>         x = y.('foo_%d' % n, None)

This is the one bit I really don't like.  y.('foobar') is arguably a
natural extension to y.foobar, but y.('foobar', None) isn't analogous
to any current syntax, and the multiple arguments make it look even
more dangerously like a call.

I think the goal should be to capture all of the readable syntax of
attribute access, not to capture all of the expressiveness of getattr.
 In Python, you already have to be explicit when you're worried if the
thing you're accessing might not be there.  So you write either:

  x.foo += 1
or
  x.foo = getattr(x, foo, 0) + 1

and you write either:

  x[bar].append(1)
or
  x.setdefault(bar, []).append(1)

Even if x.(foo, bar) wasn't scary syntax, I don't think breaking
tradition here is worth it.

But in any event, it's a very interesting idea and patch.  I'll
definitely play around with it this weekend.

Greg F



More information about the Python-ideas mailing list