[Python-ideas] new format spec for iterable types

Andrew Barnert abarnert at yahoo.com
Tue Sep 8 14:24:22 CEST 2015


On Sep 8, 2015, at 03:00, Wolfgang Maier <wolfgang.maier at biologie.uni-freiburg.de> wrote:
> 
> Hi,
> 
> in the parallel "format and print" thread, Andrew Barnert wrote:
> 
> 
> > For example, in a 5-line script I wrote last night, I've got
> > print(head, *names, sep='\t'). I could have used
> > print('\t'.join(chain([head], names)) instead--in fact, any use of
> > multi-argument print can be replaced by
> > print(sep.join(map(str, args)))--but that's less convenient, less
> > readable, and less likely to occur to novices. And there are plenty
> > of other alternatives, from
> > print('{}\t{}'.format(head, '\t'.join(names)) to
> ...
> 
> That last thing, '{}\t{}'.format(head, '\t'.join(names)), is something I find myself writing relatively often - when I do not want to print the result immediately, but store it - but it is ugly to read with its nested method calls and the separators occurring in two very different places.
> Now Andrew's comment has prompted me to think about alternative syntax for this and I came up with this idea:
> 
> What if built in iterable types through their __format__ method supported a format spec string of the form "*separator" and interpreted it as join your elements' formatted representations using "separator" ?
> A quick and dirty illustration in Python:
> 
> class myList(list):
>    def __format__ (self, fmt=''):
>        if fmt == '':
>        return str(self)
>    if fmt[0] == '*':
>            sep = fmt[1:] or ' '
>            return sep.join(format(e) for e in self)
>        else:
>            raise TypeError()
> 
> head = 99
> data = myList(range(10))
> s = '{}, {:*, }'.format(head, data)
> # or
> s2 = '{}{sep}{:*{sep}}'.format(head, data, sep=', ')
> print(s)
> print(s2)
> # 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Formatting positional argument #2 with *{sep} as the format specifier makes no sense to me. Even knowing what you're trying to do, I can't understand what *(', ') is going to pass to data.__format__, or why it should do what you want. What is the * supposed to mean there? Is it akin to *args in a function call expression, so you get ',' and ' ' as separate positional arguments? If so, how does the fmt[1] do anything useful? It seems like you would be using [' '] as the separator, and in not sure what that would do that you'd want.


More information about the Python-ideas mailing list