In Python 2.7, str.format()
accepts non-string arguments and calls the __str__
method of the value before formatting output:
class Test:
def __str__(self):
return 'test'
t = Test()
str(t) # output: 'test'
repr(t) # output: '__main__.Test instance at 0x...'
'{0: <5}'.format(t) # output: 'test ' in python 2.7 and TypeError in python3
'{0: <5}'.format('a') # output: 'a '
'{0: <5}'.format(None) # output: 'None ' in python 2.7 and TypeError in python3
'{0: <5}'.format([]) # output: '[] ' in python 2.7 and TypeError in python3
But when I pass a datetime.time
object, I get ' <5'
as output in both Python 2.7 and Python 3:
from datetime import time
'{0: <5}'.format(time(10,10)) # output: ' <5'
Passing a datetime.time
object to str.format()
should either raise a TypeError
or format str(datetime.time)
, instead it returns the formatting directive. Why is that?
'{0: <5}'.format(time(10, 10))
results in call to time(10, 10).__format__
, which returns <5
for the <5
format specifier:
In [26]: time(10, 10).__format__(' <5')
Out[26]: ' <5'
This happens because time_instance.__format__
attempts to format time_instance
using time.strftime
and time.strftime
doesn't understand the formatting directive.
In [29]: time(10, 10).strftime(' <5')
Out[29]: ' <5'
The !s
conversion flag will tell str.format
to call str
on the time
instance before rendering the result - it will call str(time(10, 10)).__format__(' <5')
:
In [30]: '{0!s: <5}'.format(time(10, 10))
Out[30]: '10:10:00'
datetime
objects support the datetime.strftime()
options when formatting:
>>> from datetime import time
>>> '{0:%H}'.format(time(10,10))
'10'
That format includes support for literal text:
>>> time(10, 10).strftime('Hour: %H')
'Hour: 10'
The >5
format is treated as literal text. You can fit your time into a 5-character column using the following format:
'{0:%H:%M}'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.