2013-06-28 20 views
8

In Python 2.7 Voglio stampare gli oggetti datetime utilizzando un modello formattato a stringa. Per qualche motivo l'uso della giustificazione sinistra/destra non stampa correttamente la stringa.Allineamento formato stringa data/ora

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 

Questo sarà il risultato:

>25 >25 

Invece di

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

C'è qualche trucco per rendere datetime oggetti di stampa utilizzando i modelli di formato stringa?

Sembra funzionare quando forzo l'oggetto datetime in str()

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

ma preferisco non avere a che fare dal momento che sto cercando di stampare un elenco di valori, alcune delle quali non sono archi. L'intero scopo di creare un modello di stringa è di stampare gli elementi nell'elenco.

Mi manca qualcosa sulla formattazione delle stringhe o questo sembra un bug python per chiunque?


SOLUZIONE

@mgilson sottolineato la soluzione che ho perso nella documentazione. link

Due bandiere di conversione sono attualmente supportate: '!' S che chiama str() sul valore, e '! R' che chiama repr().

Alcuni esempi:

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

risposta

4

Il problema qui è che datetime oggetti hanno un metodo __format__ che è fondamentalmente solo un alias per datetime.strftime. Quando si esegue la formattazione, la funzione di formattazione viene passata alla stringa '>25' che, come si è visto, dt.strftime('>25') restituisce semplicemente '>25'.

La soluzione qui per specificare che il campo deve essere formattato come una stringa in modo esplicito utilizzando !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 

(testato su entrambi python2.6 e 2,7).

+0

Sarò dannatamente Questo è esattamente ciò di cui avevo bisogno. Trovato la riga nella documentazione per questo (che ho perso). [link] (http://docs.python.org/2/library/string.html#format-string-syntax) _Due flag di conversione sono attualmente supportati: '! s' che chiama str() sul valore e '! r' che chiama repr() ._ –

+0

@ MarcelWilson - Non lo sapevo nemmeno fino a quando non sono andato a cercarlo. – mgilson

2

datetime.datetime ha format method. Hai bisogno di convertirlo 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 
+0

Questo è quello che ho fatto come soluzione finché non ho letto la soluzione di @ mgilson. È stato semplicemente imbarazzante chiamare str() quando questo è (afaik) che cosa doveva fare un modello di stringformat. –

1

Prova questo:

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

Agisce prima convertendo i datetime oggetti in una stringa, che poi possono essere formattato con il metodo format senza problemi.

Problemi correlati