2013-03-03 14 views
26

Dlaczego nie mogę używać tuple jako argumentu do sformatowania w nowym stylu ("string" .format())? Działa dobrze w starym stylu ("ciąg"%)?Nowe formatowanie stylu z krotką jako argumentem

Ten kod działa:

>>> tuple = (500000, 500, 5) 
... print "First item: %d, second item: %d and third item: %d." % tuple 

    First item: 500000, second item: 500 and third item: 5. 

I to nie:

>>> tuple = (500000, 500, 5) 
... print("First item: {:d}, second item: {:d} and third item: {:d}." 
...  .format(tuple)) 

    Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    ValueError: Unknown format code 'd' for object of type 'str' 

Nawet {R!}

>>> tuple = (500000, 500, 5) 
... print("First item: {!r}, second item: {!r} and third item: {!r}." 
...  .format(tuple)) 

    Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    IndexError: tuple index out of range 

Choć pracuje z tym sposób:

>>> print("First item: {!r}, second item: {!r} and third item: {!r}." 
...  .format(500000, 500, 50)) 

    First item: 500000, second item: 500 and third item: 5. 

Odpowiedz

45

Stary sposób formatowania użył operatora binarnego, %. Z natury może przyjąć tylko dwa argumenty. Nowy sposób formatowania wykorzystuje metodę. Metody mogą przyjmować dowolną liczbę argumentów.

Ponieważ czasami trzeba przekazać wiele rzeczy do sformatowania i jest nieco niezdarne, aby tworzyć krotki z jednym elementem przez cały czas, w starym stylu pojawił się hack: jeśli przekażesz go jako krotkę, użyje on zawartość krotki jako rzeczy do sformatowania. Jeśli przekażesz mu coś innego niż krotkę, użyje tego jako jedynej opcji do sformatowania.

Nowa metoda nie wymaga takiego hackowania: ponieważ jest to metoda, może przyjmować dowolną liczbę argumentów. Jako takie, wiele rzeczy do sformatowania trzeba będzie przekazać jako osobne argumenty. Na szczęście, można rozpakować krotka do argumentów używając *:

print("First item: {:d}, second item: {:d} and third item: {:d}.".format(*tuple)) 
17

Jak icktoofay wyjaśnił, w starym stylu formatowania, jeśli podjęta w krotce, Python automatycznie rozpakować.

Jednak nie można użyć krotki w metodzie str.format, ponieważ Python uważa, że ​​podajesz tylko jeden argument. Będziesz musiał rozpakować krotkę z operatorem *, aby przekazać każdy z elementów jako pojedynczy argument.

>>> t = (500000, 500, 5) 
>>> "First item: {:d}, second item: {:d} and third item: {:d}.".format(*t) 
First item: 500000, second item: 500 and third item: 5. 

też byś zauważył, że zmieniono nazwę zmiennej tuple do t - nie używać nazw wbudowanych zmiennych, jak można je zastąpić, a które mogłyby powodować problemy w dół toru.

+3

+1 za zmianę nazwy zmiennej. –

+1

@Volatility Myślę, że {: d} nie jest konieczne. Jeśli chcesz zamówić dane, możesz po prostu {} lub podać porządek z indeksem lub danymi w krotce {0} {1} {2} – GeoStoneMarten

+0

@GeoStoneMarten, podczas gdy ja się nieco zgadzam, użycie '{: d}' oznacza wyraźniej, że chcesz mieć tam liczbę dziesiętną (dla kogoś czytającego twój kod) – Petzku

0

To jest rzeczywiście możliwe wykorzystanie krotki jako argument do format(), jeśli ręcznie indeks krotka wewnątrz nawiasów klamrowych:

>>> t = (500000, 500, 5) 
>>> print("First item: {0[0]:d}, second item: {0[1]:d} and third item: {0[2]:d}.".format(t)) 
First item: 500000, second item: 500 and third item: 5. 

Uważam to mniej jasne niż podejście *, choć.