9

In Python 2.7 I want to print datetime objects using string formatted template. For some reason using left/right justify doesn't print the string correctly.

import datetime
dt = datetime.datetime(2013, 6, 26, 9, 0)
l = [dt, dt]
template = "{0:>25} {1:>25}" # right justify
print template.format(*l)  #print items in the list using template

This will result:

>25 >25

Instead of

  2013-06-26 09:00:00       2013-06-26 09:00:00

Is there some trick to making datetime objects print using string format templates?

It seems to work when I force the datetime object into str()

print template.format(str(l[0]), str(l[1]))

but I'd rather not have to do that since I'm trying to print a list of values, some of which are not strings. The whole point of making a string template is to print the items in the list.

Am I missing something about string formatting or does this seem like a python bug to anyone?


SOLUTION

@mgilson pointed out the solution which I missed in the documentation. link

Two conversion flags are currently supported: '!s' which calls str() on the value, and '!r' which calls repr().

Some examples:

"Harold's a clever {0!s}"        # Calls str() on the argument first
"Bring out the holy {name!r}"    # Calls repr() on the argument first
4

3 回答 3

4

这里的问题是datetime对象有一个__format__方法,它基本上只是datetime.strftime. 当您进行格式化时,格式化函数会传递字符串'>25',正如您所见,dt.strftime('>25')它只是返回'>25'.

此处的解决方法是指定字段应显式格式化为字符串!s

import datetime
dt = datetime.datetime(2013, 6, 26, 9, 0)
l = [dt, dt]
template = "{0!s:>25} {1!s:>25} " 
out = template.format(*l)
print out

(在 python2.6 和 2.7 上测试过)。

于 2013-06-28T15:44:18.483 回答
2

datetime.datetime格式方法。您需要将其转换为 str。

>>> '{:%Y/%m/%d}'.format(dt)
'2013/06/26'
>>> '{:>20}'.format(dt)
'>20'
>>> '{:>20}'.format(str(dt))
' 2013-06-26 09:00:00'

>>> import datetime
>>> dt = datetime.datetime(2013, 6, 26, 9, 0)
>>> l = [dt, dt]
>>> template = "{0:>25} {1:>25}"
>>> print template.format(*l)
>25 >25
>>> print template.format(*map(str, l))
      2013-06-26 09:00:00       2013-06-26 09:00:00
于 2013-06-28T15:43:51.957 回答
1

尝试这个:

print template.format(*map(str, l))
=>      2013-06-26 09:00:00       2013-06-26 09:00:00

它首先将datetime对象转换为字符串,然后可以使用该format方法对其进行格式化而不会出现问题。

于 2013-06-28T15:48:07.603 回答