Is this pythonic?

Frank Millman frank at chagford.com
Wed Nov 23 08:55:13 EST 2016


"Chris Angelico"  wrote in message 
news:CAPTjJmqGEwHPVyrR+Ti9bV=S5MsLt3nquF4TvE=xpeEs188yzQ at mail.gmail.com...

> On Wed, Nov 23, 2016 at 11:27 PM, Frank Millman <frank at chagford.com> 
> wrote:
> >
> > @Chris
> >>
> >> This strongly suggests that str(x) is the wrong way to get the
> >> information. You shouldn't be doing database requests inside __str__
> >> or __repr__.
> >
> >
> > I guess you are right, but still it is a pity. __str__ has been working 
> > for
> > me beautifully for a long time now. The only change is that, previously, 
> > all
> > the values had been read in or computed before calling __str__(), now I 
> > am
> > delaying the computation until requested.
> >
> > It is a bit like quantum theory. I have no way of telling whether the
> > computation has been carried out without looking at it, but the act of
> > looking at it triggers the computation. I can tell, of course, by 
> > looking at
> > the underlying attribute, but not by using the public methods.
>
> That makes sense. What you could do is have __repr__ do something like 
> this:
>
> def __repr__(self):
>     if self.has_data:
>         return "<%s: %r>" % (self.col_name, self.data)
>     return "<%s: <not fetched> >" % self.col_name
>
> I'm not sure that that would be appropriate for __str__, though; maybe
> it could return the string of data if it exists, otherwise it could
> fall back on __repr__?
>

Thanks for the ideas. I will have to experiment a bit.

There is a certain irony in all this. When I started using asyncio, I just 
converted the networking functions into coroutines and waited for it to 
stabilise. Then I wanted to extend it, and found that coroutines can only be 
called by other coroutines, and I had some long chains of function calls, so 
I backed off. Then I eventually bit the bullet, converted everything in the 
chain to a coroutine, and let it settle down again. I have done this a few 
times, and each time I sensed an improvement in the way that my entire 
application was beginning to 'flow' in an async manner, which was good. 
However, I have managed to avoid turning getval() into a coroutine, until 
now. Now I am ready to embrace the change, but this time it is Python that 
is tripping me up.

For the time being I will use 'print(await obj.__str__())', as this is a 
good compromise. Of course I don't have to use __str__, I can call it 
anything, so I will probably create a helper function to make it easy to 
call on any object.

One of the things that was deterring me from turning getval() into a 
coroutine was the inability to use a coroutine inside a comprehension. I see 
that Python 3.6 now allows this, so I must download a beta version and try 
it out.

Frank





More information about the Python-list mailing list