[Python-3000] More PEP 3101 changes incoming

Ron Adam rrr at ronadam.com
Fri Aug 3 10:08:05 CEST 2007


Talin wrote:

> (I should also mention that "a:b,c" looks prettier to my eye than 
> "a,b:c". There's a reason for this, and its because of Python syntax. 
> Now, in Python, ':' isn't an operator - but if it was, you would have to 
> consider its precedence to be very low. Because when we look at an 
> expression 'if x: a,b' we know that comma binds more tightly than the 
> colon, and so it's the same thing as saying 'if x: (a,b)'. But in any 
> case this is purely an aesthetic digression and not terribly weighty.)


+1  See below!  :-)


After a fair amount of experimenting today, I think I've found a nice 
middle ground that meets some of what both you and Guido are looking for. 
(And a bit my own preference too.)

What I've come up with is...

     '{name: specifier_1, specifier_2}'

Where the order of specifier_1 and specifier_2 are not dependent.  What 
that does is shorten the short common cases.  It's also one less thing to 
remember. :-)

The field name is set off with a colon which I think helps strengthen it's 
relationship as being a key when kwds are used as an argument source.  And 
it also resembles pythons syntax pattern more closely as you mentioned above.

The requirement for this to work is that the alignment specifier and the 
format specifiers can never start with the same characters.  Which turns 
out to be easy if you use type prefixes instead of postfixes on the format 
specifiers.

All of the following work:

The most common cases are very short and simple.

      '{0}, {1:s}, {2:r}, {3:d}'   # etc... for types

      '{0:10}'       # min field width
      '{0:.20}'      # max field width
      '{0:^20}'      # centered
      '{0:-20}'      # right justified
      '{0:+20}'      # left justified  (default)

      '{0:10.20}'    # min & max field widths together


If it starts with a letter, it's a format specifier.:

     '{0:d+}, {1:d()}, {2:d-}'

     '{0:f.3}, {1:f-.6}'


Or if it starts with '+', '-', or '^', or a digit, it's a field alignment 
specifier.


Combinations:

      '{0:10,r}'       # Specifiers are not ordered dependent.
      '{0:r,10}'       # Both of these produce the same output.

      '{0:-10,f+.3}'   ->  "  +123.346"

      '{0:-15,f()7.3}' ->  "  (    123.456)"

      '{0:^10,r}'      ->  " 'Hello'  "


For filled types such as numbers with leading zeros, a '/' character can 
separate the numeric_width from the fill character.  A numeric_width isn't 
the same as field width, so it's part of the type formatter here.

      # width/char

      '{0:d7/0}'     ->    '0000123'

      '{0:f7/0.3}'   ->    '0000123.000'


Filled widths can be used in the alignment specifiers too and follow the 
same rules.

      '{0:^16/_,s}'          ->    '____John Doe____'

      'Chapter {0:-10/.,d}'  ->    'Chapter........10'


Some motivational thoughts:

- The prefix form may make remembering formatting character sequences 
easier.  Or if not, an alphabetic look up table would work nicely as a 
reference.

- The colon and comma don't move around or change places.  That may help 
make it more readable and less likely to have bugs due to typos.

- If the format specifiers style is too close to some other existing 
languages format, but different enough to not be interchangeable, it could 
be more confusing instead of less confusing.



I have a partial python implementation with a doc test I can post or send 
to you if you want to see how the parsing is handled.  The format specifier 
parsing isn't implemented, but the top level string, field, and 
alignment_specs parsing is.  Its enough to see how it ties together.

Its a rough sketch, but it should be easy to build on.

Cheers,
    Ron


More information about the Python-3000 mailing list