On 2/13/07, Nick Coghlan <[EMAIL PROTECTED]> wrote: > Taking a step back a bit... the basic issue is that we have an attribute > namespace (compile time key determination) that we want to access in a > dictionary style (runtime key determination). > > This is currently done by switching from syntactic access to the > getattr/setattr/delattr builtin functions. > > Elsewhere in the thread, Calvin made the suggestion that, rather than > introducing new syntax, this could instead be achieved with a wrapper > class that automatically converted dict-style access into the > appropriate calls to getattr/setattr/delattr. >
In other words, an object view analagous to what Py3K is doing with keys()/values()/items(). > I've tried this out on Brett's urllib & urllib2 examples below. (calling > the new builtin attrview() to emphasise the fact that it retains a > reference to the original instance). I don't consider it any uglier than > the proposed syntax changes, and it provides a few other benefits: > > - the two-argument form is naturally available as the .get() method > on the resulting dict-like object (e.g. "attrview(obj).get(some_attr, > None)") > > - hasattr() is naturally replaced by containment testing (e.g. > "some_attr in attrview(obj)") > > - keywords/builtins are easier to look up in the documentation than > symbolic syntax > Yeah, the generalization is really nice. It allows use to ditch getattr/setattr/hasattr all without losing the expressiveness of those built-ins. > With this approach, performance would be attained by arranging to create > the view objects once, and then performing multiple dynamic attribute > accesses using those view objects. > > First urllib.py example:: > > name = 'open_' + urltype > self.type = urltype > name = name.replace('-', '_') > self_d = attrview(self) > if name in self_d: > if proxy: > return self.open_unknown_proxy(proxy, fullurl, data) > else: > return self.open_unknown(fullurl, data) > try: > if data is None: > return self_d[name](url) > else: > return self_d[name](url, data) > except socket.error, msg: > raise IOError, ('socket error', msg), sys.exc_info()[2] > > Second urllib.py example:: > > name = 'http_error_%d' % errcode > self_d = attrview(self) > if name in self_d: > method = self_d[name] > if data is None: > result = method(url, fp, errcode, errmsg, headers) > else: > result = method(url, fp, errcode, errmsg, headers, data) > if result: return result > return self.http_error_default(url, fp, errcode, errmsg, headers) > > > First urllib.py example:: > > if attr[:12] == '_Request__r_': > name = attr[12:] > get_name = 'get_' + name > if get_name in attrview(Request): > self_d = attrview(self) > self_d[get_name]() > return self_d[attr] > raise AttributeError, attr > > Second urllib2.py example:: > > handlers = chain.get(kind, ()) > for handler in handlers: > func = attrview(handler)[meth_name] > result = func(*args) > if result is not None: > return result > I also think it is just as clean as doing it any of the proposed ways:: getattr(self, name) self.[name] attrview(self)[name] So my vote is for Nick's object attribute view; +1. If we are going to do the view thing, let's go all the way! =) -Brett _______________________________________________ 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