Enumerating formatting strings

Bengt Richter bokr at oz.net
Wed Apr 20 06:43:29 EDT 2005


On Wed, 20 Apr 2005 11:01:28 +0200, Peter Otten <__peter__ at web.de> wrote:

>Bengt Richter wrote:
>
>> Parse might be a big word for
>> 
>>  >> def tupreq(fmt): return sum(map(lambda s:list(s).count('%'),
>>  >> fmt.split('%%')))
>>  ..
>>  >> tupreq('%s this %(x)s not %% but %s')
>> 
>> (if it works in general ;-)
>
>Which it doesn't:
   D'oh. (My subconscious knew that one, and prompted the "if" ;-)
>
>>>> def tupreq(fmt): return sum(map(lambda s:list(s).count('%'),
>fmt.split('%%')))
>...
>>>> fmt = "%*d"
>>>> fmt % ((1,) * tupreq(fmt))
>Traceback (most recent call last):
>  File "<stdin>", line 1, in ?
>TypeError: not enough arguments for format string
>
But that one it totally spaced on ;-/

>> Or maybe clearer and faster:
>> 
>>  >>> def tupreq(fmt): return sum(1 for c in fmt.replace('%%','') if
>>  >>> c=='%')
>>  ...
>>  >>> tupreq('%s this %(x)s not %% but %s')
>>  3
>

>Mixed formats show some "interesting" behaviour:
>
>>>> "%s %(x)s" % (1,2)
>Traceback (most recent call last):
>  File "<stdin>", line 1, in ?
>TypeError: format requires a mapping
>>>> class D:
>...     def __getitem__(self, key):
>...             return "D[%s]" % key
>...
>>>> "%s %(x)s" % D()
>'<__main__.D instance at 0x402aaf2c> D[x]'
>>>> "%s %(x)s %s" % D()
>Traceback (most recent call last):
>  File "<stdin>", line 1, in ?
>TypeError: not enough arguments for format string
>>>> "%s %(x)s %(y)s" % D()
>'<__main__.D instance at 0x402aad8c> D[x] D[y]'
>
>That is as far as I got. So under what circumstances is 
>'%s this %(x)s not %% but %s' a valid format string?
>
Yeah, I got that far too, some time ago playing % mapping, and
I thought they just didn't allow for mixed formats. My thought then
was that they could pass integer positional keys to another method
(say __format__) on a mapping object that wants to handle mixed formats.
If you wanted the normal str or repr resprensentation of a mapping
object that had a __format__ method, you'd have to do it on the args
side with str(theobject), but you'd have a way. And normal mapping objects
would need no special handling for "%s' in a mixed format context.

Regards,
Bengt Richter



More information about the Python-list mailing list