New Python 3.0 string formatting - really necessary?

MRAB google at mrabarnett.plus.com
Mon Dec 22 01:14:22 CET 2008


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'



More information about the Python-list mailing list