[Python-ideas] Outside the box string formatting idea

Ron Adam ron3200 at gmail.com
Sun Aug 9 23:20:10 CEST 2015


While the discussion of string formatting has focused on the concept of 
"format strings", it seems to me they are really format expressions.  The 
expressions in this case are a bit like comprehensions in that they have 
special syntax/rules that is only valid in a small limited context.

It may be possible to do that in this case as an actual expression rather 
than as a string and still get most of the benefits.  Shorter more 
compressed isn't always better when it comes to readability.


Consider this as a trial balloon.   If there is clear consensus against it, 
no problem.  It can be added to the rejected ideas section of PEP-498.


Below are some examples to compare from the PEP-498.

I strongly suggest posting the examples into idle or a syntax highlighting 
editor to really see what difference it makes in readability.  (it won't 
run, but the highlighting will work.)

I used % here, but that's just a place holder at this point, some other 
symbol could be used ... if this idea has any merit.  Actually it could 
even be reduced to a parentheses with items separated by spaces.


Examples from PEP:

f'My name is {name}, my age next year is {age+1}, my anniversary is 
{anniversary:%A, %B %d, %Y}.'

(% 'My name is ' name ', my age next year is ' (age+1)
  ', my anniversary is ' {anniversary ':%A, %B %d, %Y'} '.')

# The {expres fmt_spec} sytnax is only valid in (% ...) expressions.



f'He said his name is {name!r}.'

(% 'He said his name is ' {name '!r'} '.')



f'abc{expr1:spec1}{expr2!r:spec2}def{expr3:!s}ghi'

(% 'abc' {expr1 'spec1'} {expr2 '!r:spec2'} 'def' expr3 'ghi')



f'result={foo()}'

(% 'result =' foo())


x = 10
y = 'hi'
result = a' 'b' f'{x}' 'c' f'str<{y:^4}>' 'd' 'e'


result = (% 'a' 'b' x 'c' '<' {y '^4'} '>' 'd' 'e')

result = (% 'ab' x 'c<' {y '^4'} '>de')



  >>> f'{{k:v for k, v in [(1, 2), (3, 4)}}'
  '{k:v for k, v in [(1, 2), (3, 4)}'

(% {k:v for k, v in [(1, 2), (3, 4)})

This evaluates to a dictionary first.  Most expressions naturally evaluate 
from the inside out, left to right.  So there's no conflict.  It just 
converts the dict comprehension to a string.



The features allowed in (% ...)

1. Implicit concatenation is allowed for expressions separated by a space.
But only in an explicit and limited context.

2. Expressions and format specs can be combined in braces separated by a 
space.   Expressions without format specs don't need them.

3. It maintains the separation of strings and expressions.


It does require typing more quotes than a f'...' format string, but the 
separation of items by only spaces along with syntax highlighting makes it 
much more readable I think.

It's a run time expression, and not an object that can be bound to a name, 
just like f-strings.  It's result can though, that is the same as f-strings.

It removes the apparent controversy of evaluating strings.  Which f-strings 
really don't do, because they are compiled to something very similar to 
what this does.   It's just much more obvious with this suggestion that 
that isn't a problem.


Complex expressions need ()'s around them in the format expression to 
ensure it's a single value, but the parser may be able to tell  a + b, from 
a b.

This is the explicit run time expression would do what a f-string does. 
Reduce repetition of names, allow text and expressions to be interspersed 
in the order they are used with as little extra noise as possible.

The f-strings go one step further and eliminate the extra parentheses and 
quotes.  But at the cost of having them run together and loosing the syntax 
highlighting of expressions in an editor.  It also will make it harder for 
external syntax checkers to work.

It probably would need some ironing out of some the edge cases though.  A 
{expr} evaluates as a set.  Just use expr, or {expr ''}.  Things like that.

I think this is as close to an f-string as we could get and still keep the 
expressions out of the strings.


Cheers,
    Ron



















More information about the Python-ideas mailing list