[Python-Dev] PEP-498: Literal String Formatting

Guido van Rossum guido at python.org
Mon Aug 10 21:23:15 CEST 2015

On Mon, Aug 10, 2015 at 8:49 PM, Eric V. Smith <eric at trueblade.com> wrote:

> On 08/10/2015 02:44 PM, Yury Selivanov wrote:
> > On 2015-08-10 2:37 PM, Eric V. Smith wrote:
> >> This is why I think PEP-498 isn't the solution for i18n. I'd really like
> >> to be able to say, in a debugging context:
> >>
> >> print('a:{self.a} b:{self.b} c:{self.c} d:{self.d}')
> >>
> >> without having to create locals to hold these 4 values.
> >
> > Why can't we restrict expressions in f-strings to
> > attribute/item getters?
> >
> > I.e. allow f'{foo.bar.baz}' and f'{self.foo["bar"]}' but
> > disallow f'{foo.bar(baz=something)}'
> It's possible. But my point is that Barry doesn't even want
> attribute/item getters for an i18n solution, and I'm not willing to
> restrict it that much.

I also don't want to tie this closely to i18n. That is (still) very much a
wold of its own.

What I want with f-strings (by any name) is a way to generalize from
print() calls with multiple arguments. We can write

  print('Todo:', len(self.todo), '; busy:', len(self.busy))

but the same thing is more awkward when you have to pass it as a single
string to a function that just sends one string somewhere. And note that
the above example inserts a space before the ';' which I don't really like.
So it would be nice if instead we could write

  print(f'Todo: {len(self.todo)}; busy: {len(self.busy)}')

which IMO is just as readable as the multi-arg print() call[1], and
generalizes to other functions besides print().

In fact, the latter form has less punctuation noise than the former --
every time you insert an expression in a print() call, you have a
quote+comma before it and a comma+quote after it, compared to a brace
before and one after in the new form. (Note that this is an argument for
using f'{...}' rather than '\{...}' -- for a single interpolation it's the
same amount of typing, but for multiple interpolations, f'{...}{...}' is
actually shorter than '\{...}\{...}', and also the \{ part is ugly.)

Anyway, this generalization from print() is why I want arbitrary
expressions. Wouldn't it be silly if we introduced print() today and said
"we don't really like to encourage printing complicated expressions, but
maybe we can introduce them in a future version"... :-)

Continuing the print()-generalization theme, if things become too long to
fit on a line we can write

  print('Todo:', len(self.todo),
        '; busy:', len(self.busy))

Can we allow the same in f-strings? E.g.

  print(f'Todo: {len(self.todo)
        }; busy: {len(self.busy)

or is that too ugly? It could also be solved using implicit concatenation,

  print(f'Todo: {len(self.todo)}; '
        f'busy: {len(self.busy)}')

[1] Assuming syntax colorizers catch on.

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20150810/a6f8f7ab/attachment.html>

More information about the Python-Dev mailing list