Note:
Everything below applies to the
str.format
method, as well as theformat
function. In the text below, the two are interchangeable.
For every value which is passed to the format
function, Python looks for a __format__
method for that argument. Your own custom class can therefore have their own __format__
method to determine how the format
function will display and format your class and it's attributes.
This is different than the __str__
method, as in the __format__
method you can take into account the formatting language, including alignment, field width etc, and even (if you wish) implement your own format specifiers, and your own formatting language extensions.1
object.__format__(self, format_spec)
For example :
# Example in Python 2 - but can be easily applied to Python 3
class Example(object):
def __init__(self,a,b,c):
self.a, self.b, self.c = a,b,c
def __format__(self, format_spec):
""" Implement special semantics for the 's' format specifier """
# Reject anything that isn't an s
if format_spec[-1] != 's':
raise ValueError('{} format specifier not understood for this object', format_spec[:-1])
# Output in this example will be (<a>,<b>,<c>)
raw = "(" + ",".join([str(self.a), str(self.b), str(self.c)]) + ")"
# Honor the format language by using the inbuilt string format
# Since we know the original format_spec ends in an 's'
# we can take advantage of the str.format method with a
# string argument we constructed above
return "{r:{f}}".format( r=raw, f=format_spec )
inst = Example(1,2,3)
print "{0:>20s}".format( inst )
# out : (1,2,3)
# Note how the right align and field width of 20 has been honored.
Note:
If your custom class does not have a custom
__format__
method and an instance of the class is passed to theformat
function, Python2 will always use the return value of the__str__
method or__repr__
method to determine what to print (and if neither exist then the defaultrepr
will be used), and you will need to use thes
format specifier to format this. With Python3, to pass your custom class to theformat
function, you will need define__format__
method on your custom class.