Generating getter methods with exec
Neal Norwitz
neal at metaslash.com
Mon Mar 18 18:36:51 EST 2002
Stefan Schwarzer wrote:
>
> Hello Neal
>
> thank you for your answer. :)
>
> Neal Norwitz wrote:
> > You don't need to generate code. This should do what you want:
> >
> > class GetterTest:
> > def __init__(self):
> > self._dict = {'key1': 'one',
> > 'key2': 'two',
> > 'key3': 'three'}
> >
> > def __getattr__(self, attr):
> > try:
> > return self._dict[attr]
> > except KeyError:
> > raise AttributeError, "getting attribute '%s'" % attr
> >
> > >>> g = GetterTest()
> > >>> g.key1
> > 'one'
> > >>> g.key2
> > 'two'
> > >>> g.key3
> > 'three'
> > >>> g.key4
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > File "<stdin>", line 8, in __getattr__
> > AttributeError: getting attribute 'key4'
>
> Yes, that's the straightforward solution. :-)
>
> On the other hand, what I posted was a simplified example. Finally, I
> will have several dictionary-like objects and not all of their items
> should be accessible by get/set methods (only some of the corresponding
> attributes belong to the public interface). I'm a bit afraid the overhead
> of dynamically making all the decisions for every access might be slow
> (though it may well be that all will be fast enough).
>
> So to rephrase the problem a bit: I would like to generate simple getters
> and setters with rather little decision overhead during the actual accesses.
:-) Well in that case:
class GetterTest1:
def __init__(self):
self._dict = {'key1': 'one',
'key2': 'two',
'key3': 'three'}
def _make_getters(self, dict_name, key_list):
for key in key_list:
code = "def %(key)s(): return %(dict_name)s['%(key)s']\n" % vars()
exec code in self.__dict__, self.__dict__
-----------------
The problem is the distinction between bound vs unbound methods.
BTW, this version is about 3 times faster than the previous. It
took .03 seconds to call key1 10,000 times vs. .1 seconds.
Neal
More information about the Python-list
mailing list