New Python 3.0 string formatting - really necessary?

Aaron Brady castironpi at gmail.com
Mon Dec 22 03:11:05 CET 2008


On Dec 21, 6:14 pm, MRAB <goo... at mrabarnett.plus.com> wrote:
> Aaron Brady wrote:
> > On Dec 21, 10:58 am, MRAB <goo... at mrabarnett.plus.com> wrote:
> >> Aaron Brady wrote:
> >>> On Dec 21, 10:31 am, MRAB <goo... at mrabarnett.plus.com> wrote:
> > snip
> >>>> The original format is a string. The result of '%' is a string if
> >>>> there's only 1 placeholder to fill, or a (partial) format object (class
> >>>> "Format"?) if there's more than one. Similarly, the format object
> >>>> supports '%'. The result of '%' is a string if there's only 1
> >>>> placeholder to fill, or a new (partial) format object if there's more
> >>>> than one.
> >>>>  >>> f = "%r %i"
> >>>>  >>> type(f)
> >>>> <type 'str'>
> >>>>  >>> f = f % (2, 3, 4)
> >>>>  >>> type(f)
> >>>> <type 'Format'>
> >>>>  >>> f = f % 1
> >>>>  >>> type(f)
> >>>> <type 'str'>
> >>> Alright, so how are you handling:
> >>>>>> f= "%s %i"
> >>>>>> type( f )
> >>> <type 'str'>
> >>>>>> f= f% '%i'  #now '%i %i'
> >>>>>> type( f )
> >>> <type 'Format'>
> >>>>>> f= f% 1
> >>>>>> type( f )
> >>> ?
> >>> In other words, are you slipping '1' in to the very first available
> >>> slot, or the next, after the location of the prior?
> >> Let's assume that Format objects display their value like the equivalent
> >> string format:
>
> >>  >>> f = "%r %i"
> >>  >>> f
> >> '%r %i'
> >>  >>> f = f % (2, 3, 4)
> >>  >>> f
> >> <Format '(2, 3, 4) %i'>
> >>  >>> f = f % 1
> >>  >>> f
> >> '(2, 3, 4) 1'
>
> >>  >>> f = "%s %i"
> >>  >>> f
> >> '%s %i'
> >>  >>> f = f % '%i'
> >>  >>> f
> >> <Format '%%i %i'>
> >>  >>> f = f % 1
> >>  >>> f
> >> '%%i 1'
>
> > I assume you meant '%i 1' since there are no more flags in f, and it's
> > returned to a regular string.
>
> Correct.
>
> > 'f %= 1' doesn't work any more as in-place modulo, since one time, 'f'
> > is a Format object, the other, 'f' is a string.  Just raise an
> > exception for that (or assign to __class__ IINM if I'm not mistaken).
>
> All assignments rebind, even the augmented form:
>
>  >>> class C1(object):
>         def __mod__(self, value):
>                 return C2()
>
>  >>> class C2(object):
>         def __mod__(self, value):
>                 return C2()
>
>  >>> f = C1()
>  >>> f
> <__main__.C1 object at 0x00D144F0>
>  >>> f % 0
> <__main__.C2 object at 0x00D143F0>
>  >>> f %= 0
>  >>> f
> <__main__.C2 object at 0x00D145B0>
>
>
>
> > Actually, the class you showed is kind of nifty.  Tuples are correctly
> > interpolated.  I think on the whole you'll use more parenthesis, since
> > each term in the tuple appears separately, and might be an expression
> > (have a lower-precedence op.), as well as more modulo signs.
>
> > You can currently do-it-yourself, you just need a constructor in the
> > format string.
>
> >>>> f = Format("%r %i")
> >>>> type(f)
> > <type 'Format'>
> >>>> f = f % (2, 3, 4)
> >>>> type(f)
> > <type 'Format'>
>
> > Or, as someone suggested earlier, a new literal marking:
>
> Yes, I suggested that earlier, but it isn't needed because you can
> create a format object with "Format(string)". However, most of the time
> you won't bother to create a format object explicitly because of:
>
> class str(object):
>      def __mod__(self, value):
>          return Format(self) % value
>
> >>>> f = f"%r %i"
> >>>> type(f)
> > <type 'Format'>
>
>  >>> # Explicitly
>  >>> f = Format("%r %i")
>  >>> f
> <Format '%r %i'>
>  >>> f % (2, 3, 4)
> <Format '(2, 3, 4) %i'>
>  >>>
>  >>> # Implicitly, relying on the __mod__ method of str
>  >>> f = "%r %i"
>  >>> f
> '%r %i'
>  >>> f % (2, 3, 4)
> <Format '(2, 3, 4) %i'>
>
> I'd also like to add that there's nothing to prevent format objects from
> having other methods where multiple placeholders can be filled in one call:
>
>  >>> # By position
>  >>> f = Format("%r %i")
>  >>> f
> <Format '%r %i'>
>  >>> f.fill([(2, 3, 4), 1])
> '(2, 3, 4) 1'
>  >>>
>  >>> # By name
>  >>> f = Format("%{tuple}r %{int}i")
>  >>> f
> <Format '%{tuple}r %{int}i'>
>  >>> f.fill({"tuple": (2, 3, 4), "int": 1})
> '(2, 3, 4) 1'

You're choosing to favor the '.chain()' method over the '.fill()'
method for the behavior of '%'.  I don't think you've justified it
though.

>>> Format( "%r %i" ).chain( ( 2, 3, 4 ) ).chain( 0 )
'(2, 3, 4) 0'
>>> Format( "%r %i" ).fill( ( 2, 3, 4 ), 0 )
'(2, 3, 4) 0'

Plus, I almost think we've almost attained defeating the purpose.



More information about the Python-list mailing list