From: Ethan Furman on 2 Apr 2010 15:38 Patrick Maupin wrote: > On Apr 2, 1:21 pm, Ethan Furman <et...(a)stoneleaf.us> wrote: >> For this type of situation, my preference would be: >> >> class spam(object): >> def __call__(self, x, y, z): >> try: >> mongo = self.mongo >> except AttributeError: >> mongo = self.mongo = heavy_lifting_at_runtime() >> return frobnicate(x, y, z, mongo) >> spam = spam() >> >> No extra objects, out-of-place underscores, etc. >> >> ~Ethan~ > > Well, I'm not a big fan of unnecessary try/except, so I would at least > change it to: > > class spam(object): > def __getattr__(self, name): > if name != 'mongo': > raise AttributeError > self.mongo = heavy_lifting_at_runtime() > return self.mongo > def __call__(self, x, y, z): > return frobnicate(x, y, z, self.mongo) > spam = spam() > > Regards, > Pat Sounds like a personal preference issue, rather than a necessary / unnecessary issue -- after all, if you call that function a thousand times, only once is mongo not defined... clearly the exception. ;) ~Ethan~
From: Patrick Maupin on 2 Apr 2010 15:39 On Apr 2, 2:38 pm, Ethan Furman <et...(a)stoneleaf.us> wrote: > Patrick Maupin wrote: > > On Apr 2, 1:21 pm, Ethan Furman <et...(a)stoneleaf.us> wrote: > >> For this type of situation, my preference would be: > > >> class spam(object): > >> def __call__(self, x, y, z): > >> try: > >> mongo = self.mongo > >> except AttributeError: > >> mongo = self.mongo = heavy_lifting_at_runtime() > >> return frobnicate(x, y, z, mongo) > >> spam = spam() > > >> No extra objects, out-of-place underscores, etc. > > >> ~Ethan~ > > > Well, I'm not a big fan of unnecessary try/except, so I would at least > > change it to: > > > class spam(object): > > def __getattr__(self, name): > > if name != 'mongo': > > raise AttributeError > > self.mongo = heavy_lifting_at_runtime() > > return self.mongo > > def __call__(self, x, y, z): > > return frobnicate(x, y, z, self.mongo) > > spam = spam() > > > Regards, > > Pat > > Sounds like a personal preference issue, rather than a necessary / > unnecessary issue -- after all, if you call that function a thousand > times, only once is mongo not defined... clearly the exception. ;) > > ~Ethan~ Well, I think the whole discussion has basically been about personal preference. OTOH, but if you call the function a few million times, you might find the cost of try/except to be something that you would rather not incur -- it might become a performance issue rather than a personal choice issue. On the other OTHER hand, if you call the function a few billion times, performance weighs more heavily in favor of the closure approach rather than the object approach, since local variable lookup is so much cheaper. Regards, Pat
From: Ethan Furman on 2 Apr 2010 16:33 Patrick Maupin wrote: [snippage] > Well, I think the whole discussion has basically been about personal > preference. OTOH, but if you call the function a few million times, > you might find the cost of try/except to be something that you would > rather not incur -- it might become a performance issue rather than a > personal choice issue. On the other OTHER hand, if you call the > function a few billion times, performance weighs more heavily in favor > of the closure approach rather than the object approach, since local > variable lookup is so much cheaper. Indeed. I was surprised to find your __getattr__ approach faster than the try/except approach (about 20% on my machine). I'll have to think about that for future situations like this. My main point, though, was using __call__, and not some weird _ method. ;) ~Ethan~
From: Patrick Maupin on 2 Apr 2010 16:42 On Apr 2, 3:33 pm, Ethan Furman <et...(a)stoneleaf.us> wrote: > My main point, though, was using __call__, and not some weird _ method. ;) Yes, __call__ is good. In general, not naming things that don't need to be named is good (but if you have too many of them to keep track of, then, obviously, they need to be named, hence named tuples). But I didn't need to address that, since you already did :-)
From: kj on 2 Apr 2010 18:59
In <Xns9D4EC021DC8EAduncanbooth(a)127.0.0.1> Duncan Booth <duncan.booth(a)invalid.invalid> writes: >class Spam(object): > mongo = None > def __call__(self, x, y, z): > if self.mongo is None: > self.mongo = heavy_lifting_at_runtime() > return frobnicate(x, y, z, self.mongo) >spam = Spam() >ham = spam(1, 2, 3) I really like this. Thanks. >That's natural and readable. From reading this thread, and the "(a==b) ? 'Yes' : 'No'" one, the inescapable conclusion is that "readability" (like beauty) is very much in the eye of the beholder, or, in this case, in the eye of Guido. ~K |