Pardon me for the run-by comment.
Your proposed double-dot syntax foo..bar (that is something whose
__*item__ methods you want to invoke) is visually indistinguishable
from a mistyped goo..baz (whose __*item__ methods you do not want to
invoke) . The only way a 3rd party could know what you meant is if
they subsequently scanned all nearby code to see if that particular
access pattern was repeated, or if they knew that you really wanted to
access the contents of the dictionary and not the attributes of an
object.
It also seems to me that the use of a dictionary instead of a
container for attributes (via AttrDict) is also a mistake (I've
written these myself, but only because of their convenience, not
because I like them conceputally). Consistency for the sake of sanity
is something that I strive for, especially when writing code that
others are to read. If you feel the need to have an AttrDict class,
might I suggest a very simple wrapper that ensures that you aren't
mixing access patterns that would confuse.
class AttrDict(object):
... def __init__(self, dict):
... self.__dict__ = dict
...
b = {}
c = AttrDict(b)
c.a
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'AttrDict' object has no attribute 'a'
b['a'] = 1
c.a
1
No need to implement *any* magic method beyond __init__. Of course you
can't access it like a dictionary, but I thought that was what you
were trying to avoid.
The claimed reduction in keystrokes is false economy. While you may
save a few keystrokes (the square brackets and quote marks) for some
accesses, "syntax should not look like grit on my monitor", and an
extra period is the most grit-like of any syntax I've ever seen.
And finally, for the sake of consistency, if foo..bar is allowed, why
not allow for foo..1? Lists are also used with container[index]? Oh,
because of the ambiguity. Did we mean foo[1], or did we mean foo['1'].
Therein lies the rub, as while previously the behavior was consistent
for all container types (foo[bar] does the same thing, for all
possible bar), now accessing a string key in a container gets special
syntax via foo..string . That doesn't feel right to me.
For all of these reasons, I'm -1 .
Regards,
- Josiah
On Thu, Mar 24, 2011 at 8:20 AM, Jameson Quinn <jameson.quinn@gmail.com> wrote:
2011/3/24 Brian Curtin <brian.curtin@gmail.com>
On Thu, Mar 24, 2011 at 06:40, Jameson Quinn <jameson.quinn@gmail.com>
wrote:
"class attrdict" is a perennial dead-end for intermediate pythonistas who
want to save 3 characters/5 keystrokes for item access. Other languages such
as javascript allow "somedict.foo" to mean the same as "somedict['foo']", so
why not python? Well, there are a number of reasons why not, beginning with
all the magic method names in python.
But saving keystrokes is still a reasonable goal.
Code is read far more often than it is written, so readability tends to
count more than most other metrics.
So what about a compromise? Allow "somedict..foo", with two dots, to take
that place. It still saves 2 characters (often 4 keystrokes; and I find even
', "[", or "]" harder to type than ".").
I don't see the benefit, but maybe it'll save a few bytes in file size.
Anyone reviewing your code now has to think "does this need one or two
dots?"
Anyways, why not just do something like this:
class AttrDict(dict):
def __getattr__(self, attr):
return super(AttrDict, self).__getitem__(attr)
d = AttrDict()
d["a"] = 1
d.a
1
There are a few reasons not to do it your way. For one, you could easily
forget about one of the built-in dict methods (e.g. d.get != d["get"]). For
another, if you look on the web, you'll find at least 15 different recipes
for that thing you just made, several of which have more-or-less subtle
errors waiting to get you. Furthermore, the whole point is to have this
available for built-in dicts. Say you get a dict as json - you can either
subclass your own json decoder, with all the pitfalls, or you can explicitly
pass the decoded dict to AttrDict, causing an extra object to be created and
obfuscating your code. And finally, who wants to copy that AttrDict code for
the 137th time?
As for the question of "one or two dots", it's exactly the same question you
face now with "dot or bracket", so I don't see the problem.
It's not merely a matter of saving keystrokes. To me, it would be actually
easier to read code in this style. When I'm doing things like accessing my
json data, that is essentially attribute access; why should my syntax
colorer color it the same as my UI strings?
In sum:
-Saves keystrokes
-saves bugs from miscooked recipes
-faster and less memory than any such recipe
-more-readable code
-very low-risk for old code
Jameson
_______________________________________________
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/josiah.carlson%40gmail.com