[Tutor] pythonic
Steven D'Aprano
steve at pearwood.info
Mon Apr 2 09:28:59 EDT 2018
On Mon, Apr 02, 2018 at 06:49:52AM -0600, Mats Wichmann wrote:
> On 04/02/2018 02:56 AM, Alan Gauld via Tutor wrote:
> > On 02/04/18 04:19, Steven D'Aprano wrote:
> >> On Sun, Apr 01, 2018 at 10:58:51PM +0100, Alan Gauld via Tutor wrote:
> >>> On01/04/18 20:20, Albert-Jan Roskam wrote:
> >>>> fmt="%Y-%m-%d %H:%M\n"
> >>>> f.write(now.strftime(fmt))
> >>>> Lately I've been using format(), which uses __format__, because I find it slightly more readable:
> >>>> format(datetime.now(), "%Y-%m-%d %H:%M")
> >>> Interesting,
> >>> I didn't know that format() recognised the datetime format codes.
> >> It doesn't. It is the datetime object that recognises them. format()
> >> merely passes the format string to the datetime.__format__ method, which
> >> is what recognises the codes. It doesn't care what it is.
> > Aha! That makes sense. I've never really used format() so have never
> > bothered to find out how it works. To the point that until this thread I
> > hadn't realized we even had a __format__() operator.
> >
> > As I said, I need to do some reading. Obviously a gap in my python
> > education.
> >
>
> so since we're all learning things here, how would this play out with
> the new f-strings?
I don't think f-strings are even a bit Pythonic.
They look like string constants, but they're actually a hidden call to
eval().
py> x = 2
py> f'hello {3*x}'
'hello 6'
So they can execute arbitrary code that has arbitrary side-effects:
py> L = []
py> f'hello {L.append(1) or 99}'
'hello 99'
py> L
[1]
By my count, they violate at least three of the Zen of Python:
Explicit is better than implicit.
Simple is better than complex.
Special cases aren't special enough to break the rules.
They can only be used once, and are not re-usable (unlike proper
templates):
py> x = 2
py> template = f'x = {x}' # gets the value of x now
py> print(template)
x = 2
py> x = 99
py> print(template) # still has the old value of x
x = 2
However, they do use the same mechanism as format():
py> from datetime import datetime
py> t = datetime.now()
py> format(t, '%H:%M')
'23:22'
py> f'{t:%H:%M}'
'23:22'
--
Steve
More information about the Tutor
mailing list