On 2/9/07, Ben North email@example.com wrote:
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.