pythonstringformatpython-2.6built-in

Why does Python have a format function as well as a format method


The format function in builtins seems to be like a subset of the str.format method used specifically for the case of a formatting a single object.

eg.

>>> format(13, 'x')
'd'

is apparently preferred over

>>> '{0:x}'.format(13)
'd'

and IMO it does look nicer, but why not just use str.format in every case to make things simpler? Both of these were introduced in 2.6 so there must be a good reason for having both at once, what is it?

Edit: I was asking about str.format and format, not why we don't have a (13).format


Solution

  • I think format and str.format do different things. Even though you could use str.format for both, it makes sense to have separate versions.

    The top level format function is part of the new "formatting protocol" that all objects support. It simply calls the __format__ method of the object it is passed, and returns a string. This is a low-level task, and Python's style is to usually have builtin functions for those. Paulo Scardine's answer explains some of the rationale for this, but I don't think it really addresses the differences between what format and str.format do.

    The str.format method is a bit more high-level, and also a bit more complex. It can not only format multiple objects into a single result, but it can also reorder, repeat, index, and do various other transformations on the objects. Don't just think of "{}".format(obj). str.format is really designed for more about complicated tasks, like these:

    "{1} {0} {1!r}".format(obj0, obj1) # reorders, repeats, and and calls repr on obj1
    "{0.value:.{0.precision}f}".format(obj) # uses attrs of obj for value and format spec
    "{obj[name]}".format(obj=my_dict) # takes argument by keyword, and does an item lookup
    

    For the low-level formatting of each item, str.format relies on the same machinery of the format protocol, so it can focus its own efforts on the higher level stuff. I doubt it actually calls the builtin format, rather than its arguments' __format__ methods, but that's an implementation detail.

    While ("{:"+format_spec+"}").format(obj) is guaranteed to give the same results as format(obj, format_spec), I suspect the latter will be a bit faster, since it doesn't need to parse the format string to check for any of the complicated stuff. However the overhead may be lost in the noise in a real program.

    When it comes to usage (including examples on Stack Overflow), you may see more str.format use simply because some programmers do not know about format, which is both new and fairly obscure. In contrast, it's hard to avoid str.format (unless you have decided to stick with the % operator for all of your formatting). So, the ease (for you and your fellow programmers) of understanding a str.format call may outweigh any performance considerations.