Есть такая запись форматирования
>>> "{0:>10}".format(42)
" 42"
Что означает: сделать строку шириной 10 символов и переданный аргумент выровнять по правую сторону.
Есть аналог для перемещения влево и по центру, но не об этом сейчас.
Что будет, если подать в такую строку кастомный класс?
>>> class MyClass:
>>> pass
>>> c = MyClass()
>>> "{0:>10}".format(c)
TypeError: unsupported format string passed to MyClass.__format__
Упс, ошибка форматирования! То есть Python говорит что у нашего класса нет метода ˍˍformatˍˍ. Даже ˍˍstrˍˍ и ˍˍreprˍˍ не помогут.
>>> class MyClass:
>>> def __str__(self):
>>> return 'My Class'
>>> def __repr__(self):
>>> return '<My Class>'
>>> c = MyClass()
>>> "{0:>20}".format(c)
TypeError: unsupported format string passed to MyClass.__format__
Что ж, это легко решается добавлением метода ˍˍformatˍˍ. Но а что если это не ваши классы и изменить исходники никак нельзя? Можно сделать небольшое преобразование, например такими способами:
>>> "{0:>20}".format(str(c))
" My Class"
>>> "{0:>20}".format(repr(c))
" <My Class>"
Но лучше использовать явный конвертор, то есть механизмы самого форматирования. В таком случае необходимое действия будет жёстко указано в самом паттерне.
Чтобы "конвертнуть" свой класс с помощью ˍˍstrˍˍ пишем так:
"{0!s:>20}".format(c)
А чтобы преобразование сделалось с помощью ˍˍreprˍˍ, пишем так:
"{0!r:>20}".format(c)
Теперь не важно какой класс прилетит, всё сработает!
Только учтите, если не определить методы ˍˍstrˍˍ и ˍˍreprˍˍ то получится что-то типа:
"<MyClass object at 0x7f27a62ed278>"
Но хотя бы не будет ошибки.
PS. А если определить метод ˍˍformatˍˍ, то можно и другие буковки использовать для специфичных преобразований!
#tricks