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
tldr;
format
just callsobj.__format__
and is used by thestr.format
method which does even more higher level stuff. For the lower level it makes sense to teach an object how to format itself.It is just syntactic sugar
The fact that this function shares the name and format specification with
str.format
can be misleading. The existence ofstr.format
is easy to explain: it does complex string interpolation (replacing the old%
operator);format
can format a single object as string, the smallest subset ofstr.format
specification. So, why do we needformat
?The
format
function is an alternative to theobj.format('fmt')
construct found in some OO languages. This decision is consistent with the rationale forlen
(on why Python uses a functionlen(x)
instead of a propertyx.length
like Javascript or Ruby).When a language adopts the
obj.format('fmt')
construct (orobj.length
,obj.toString
and so on), classes are prevented from having an attribute calledformat
(orlength
,toString
, you got the idea) - otherwise it would shadow the standard method from the language. In this case, the language designers are placing the burden of preventing name clashes on the programmer.Python is very fond of the PoLA and adopted the
__dunder__
(double underscores) convention for built-ins in order to minimize the chance of conflicts between user-defined attributes and the language built-ins. Soobj.format('fmt')
becomesobj.__format__('fmt')
, and of course you can callobj.__format__('fmt')
instead offormat(obj, 'fmt')
(the same way you can callobj.__len__()
instead oflen(obj)
).Using your example:
Which one is cleaner and easier to type? Python design is very pragmatic, it is not only cleaner but is well aligned with the Python's duck-typed approach to OO and gives the language designers freedom to change/extend the underlying implementation without breaking legacy code.
The PEP 3101 introduced the new
str.format
method andformat
built-in without any comment on the rationale for theformat
function, but the implementation is obviously just syntactic sugar:And here I rest my case.
What Guido said about it (or is it official?)
Quoting the very BDFL about
len
:source: pyfaq@effbot.org (original post here has also the original question Guido was answering). Abarnert suggests also:
Is this a practical concern or just syntax nitpicking?
This is a very practical and real-world concern in languages like Python, Ruby or Javascript because in dynamically typed languages any mutable object is effectively a namespace, and the concept of private methods or attributes is a matter of convention. Possibly I could not put it better than abarnert in his comment:
For example, I just left Ember.js in favor of Angular.js because I was tired of namespace conflicts in Ember; Angular handles this using an elegant Python-like strategy of prefixing built-in methods (with
$thing
in Angular, instead of underscores like python), so they do not conflict with user-defined methods and properties. Yes, the whole__thing__
is not particularly pretty but I'm glad Python took this approach because it is very explicit and avoid the PoLA class of bugs regarding object namespace clashes.I think
format
andstr.format
do different things. Even though you could usestr.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 whatformat
andstr.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: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 builtinformat
, rather than its arguments'__format__
methods, but that's an implementation detail.While
("{"+format_code+"}").format(obj)
is guaranteed to give the same results asformat(obj, format_code)
, 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 aboutformat
, which is both new and fairly obscure. In contrast, it's hard to avoidstr.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 astr.format
call may outweigh any performance considerations.