On 5/14/07, <b class="gmail_sendername">Warren Stringer</b> <<a href="mailto:warren@muse.com">warren@muse.com</a>> wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Last Thursday's newbie night was inspiring!</blockquote><div><br>Glad you liked it!<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Is there a more idiomatic way of expressing this? Perhaps a faster, yet<br>pythy solution?</blockquote><div><br></div></div>I would change things to be more idiomatic in several ways:<br>a. use "if key in somedict" rather than "if
somedict.has_key(key)"<br>b. know that __getattr__ is only called if OTHER normal ways to<br> get the attribute fail (so don't bother checking if one of such<br> normal ways would have succeeded!) -- __setattr__ is different
<br>c. add unit tests to make sure one can change and refactor with<br> much more confidence<br><br>I'm not going to tackle (c), but, without testing, here's roughly how I might rephrase things...:<br><br><pre>
<font size="4">class Tr3(dict):<br><br> _ok_attrs = set('who what child parent'.split())<br><br> def __init__(self, parent=None, who='tr3'):<br> self.who = who<br> self.what = None<br>
self.child = {}<br> self.parent = parent<br> <br> def __call__(self, v=None):<br> self.what = v<br><br> def __str__(self):<br> if self.parent is not None:<br> return '%s.%s' % (
self.parent, self.who)<br> else:<br> return self.who<br><br> def __getattr__(self, name):<br> if name[:2] == '__' == name[-2:]: <br> return dict.__getattr__(self, name)<br> if name not in
self.child:<br> self.child[name] = Tr3(self, name)<br> return self.child[name]<br><br> def __setattr__(self, name, value):<br> if name in self._ok_attrs or name in self.__dict__:<br> self.__dict__[name] = value
<br> else:<br> if name not in self.child:<br> self.child[name] = Tr3(self, name)<br> self.child[name].what = value<br><br></font><font style="font-family: times new roman,serif;" size="4">
The intent is to get the same semantics as you had on your page, just in a slightly more fluid</font><font style="font-family: times new roman,serif;" size="4"> and idiomatic way.<br>(I'm not quite sure how any name except those in _ok_attrs would ever end up in self.__dict__, so I do
<br>suspect that test in __setattr__ can be simplifited, but as I said I'm trying to keep the same semantics as<br>you had, so I avoided performing that simplification myself).<br><br>As I abhor repetition so deeply, I'd probably add a tiny auxiliary method:
<br><br></font><font style="font-family: courier new,monospace;" size="4"> def _setInChild(self, name):</font><font style="font-family: times new roman,serif;" size="4"><br></font><font><font size="4"> if name not in
self.child:<br> self.child[name] = Tr3(self, name)<br></font></font><br><font><font style="font-family: times new roman,serif;" size="4">and call self._setInChild(name) in the two places which now have, instead, repetitions of this guarded
<br>assignment (but I realize that most people don't abhor repetition as intensely as I do:-).<br><br></font></font><font style="font-family: times new roman,serif;" size="4"><br>Alex<br><br></font></pre>