Note:
Everything below applies to the
str.formatmethod, as well as theformatfunction. 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 theformatfunction, 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 defaultreprwill be used), and you will need to use thesformat specifier to format this. With Python3, to pass your custom class to theformatfunction, you will need define__format__method on your custom class.