Yet another Python textbook

Ian Kelly ian.g.kelly at gmail.com
Thu Nov 22 19:27:10 CET 2012


On Thu, Nov 22, 2012 at 5:24 AM, Colin J. Williams <cjw at ncf.ca> wrote:
> From my reading of the docs, it seems to me that the three following should
> be equivalent:
>
>   (a) formattingStr.format(values)
> with
>   (b) format(values, formattingStr)
> or
>   (c) tupleOfValues.__format__(formattingStr
>
> Example:
> print('{:-^14f}{:^14d}'.format(-25.61, 95 ))
> print(format((-25.61, 95), '{:-^14f}{:^14d}'))
> (-25.61, 95 ).__format__('{:-^14f}{:^14d}')
>
> The second fails, perhaps because values can only be a single value.
> The third fails, the reason is unclear.

The latter two (which are more or less equivalent) fail because they are
intended for invoking the formatting rules of a single value.  The
string argument to each of them is not a format string, but a "format
specification", which in a format string is only the part that goes
inside the curly braces and after the optional colon.  For example, in
this format string:

>>> 'Hello world {0!s:_>4s}'.format(42)
'Hello world __42'

The format specifier here is "_>4s":

>>> format('42', '_>4s')
'__42'

The valid format specifiers depend upon the type of the object being formatted:

>>> format(42, '04x')
'002a'

>>> format(datetime(2012, 11, 22, 11, 17, 0), 'The time is %Y %d %m %H:%M:%S')
'The time is 2012 22 11 11:17:00'

Custom types can implement custom format specifications by overriding
the __format__ method:

>>> class Foo:
...     def __init__(self, value):
...         self.value = value
...     def __format__(self, spec):
...         if spec == 'a':
...             return str(self.value)
...         if spec == 'b':
...             return ''.join(reversed(str(self.value)))
...         raise ValueError("Unknown format code {!r}".format(spec))
...
>>> format(Foo(42), 'a')
'42'
>>> format(Foo(42), 'b')
'24'

The same format specifications can then also be passed to str.format:

>>> '{0:a} reversed is {0:b}'.format(Foo(42))
'42 reversed is 24'

Unfortunately, there does not seem to be a good reference to the
format specifications available for built-in types beyond basic
strings and numbers.  I only knew about the datetime example because
it is used in an example in the str.format docs.  The
datetime.__format__ implementation (which seems to be just a thin
wrapper of datetime.strftime) does not seem to be documented anywhere
in the datetime module docs.


More information about the Python-list mailing list