[Python-ideas] Have a "j" format option for lists

Eric V. Smith eric at trueblade.com
Thu May 10 08:09:21 EDT 2018


On 5/10/18 7:02 AM, Rhodri James wrote:
> If so, does anything in that string need escaping, like say braces or
> other "j"s?  I'm not sure if format specifiers currently allow arbitrary
> text (I don't think they do, but I'm not sure), which might make this a
> more serious undertaking than it first looks.  Alternatively, are
> certain characters forbidden in this implicit join string?

A format spec can contain anything. Its interpretation is completely 
left to the type being formatted. For example, a datetime supports a 
strftime() string, which can be anything:

 >>> '{:today is %Y-%m-%d}'.format(datetime.datetime.now())
'today is 2018-05-10'

In str.format(), there's a restriction that the format spec can't 
contain a closing brace }, but that's solely a restriction of the string 
scanning that's going on, and not a function of the __format__ protocol 
itself. For example:

 >>> format(datetime.datetime.now(), 'today is %Y-%m-%d {tada!}')
'today is 2018-05-10 {tada!}'

I always suggest to people that they don't look at f-strings or 
str.format() when coming up with examples, but instead use format() or 
obj.__format__() to more clearly see what's happening. In Facundo's 
original example:

authors = ["John", "Mary", "Estela"]
"Authors: {:, j}".format(authors)

it's best to think of this as:

"Authors: " + format(authors, ', j')

or the equivalent (in this case):

"Authors: " + authors.__format__(', j')

authors is a list in this example, so list.__format__() would have to 
understand the format spec ', j'. Okay, that's probably doable (although 
I'm not advocating it!). But you really don't want this to work just for 
lists. What about:

def authors1():
    yield "John"
    yield "Mary"
    yield "Estela"
format(authors1(), ', j')

How would that work? Would generators grow a __format__()? It's not 
possible to add this functionality to every iterator past, present, and 
future.

This is why I think a wrapper that adds a __format__(), which itself 
calls str.join(), is the only way to handle this. This is what I showed 
in my earlier response as the Join class. And at that point, I don't 
think it's really worth the hassle over just calling str.join().

Eric


More information about the Python-ideas mailing list