Obsah

Formátování výstupu

Na řadě příkladů jsme se přesvědčili, že už máme prostředky, jak v poměrně širokém rozsahu upravovat formát hodnot určených pro výstup (tisk na konzoli). Nyní si představíme metodu format datového typu řetězec, která má ještě větší možnosti užití a je univerzálním a nejpoužívanějším způsobem formátování v Pythonu.

Formátovací řetězec

Formátovací řetězec poměrně jednoduše pomocí jakéhosi mini-jazyka popisuje, jakým způsobem naložit s řetězcovými i číselnými hodnotami tak, aby grafický tvar výstupu odpovídal očekávanému výsledku. Kromě pevné části má sekce, které jsou doplněny na základě hodnot předaných parametrů. Výsledkem volání metody je pak řetězec, se kterým program může dále pracovat (např. jej pomocí funkce print vytisknout).

vystup = "Vytiskneme {} a {}.".format("alfa", "beta")

Útržek kódu ukazuje typické použití: metoda format je aplikována na řetězcovou konstantu, která určuje formátování. Kromě pevného obsahu obsahuje dvě sekce vyznačené složenými závorkami, do kterých se doplní hodnoty parametrů předaným metodě (v našem případě dva řetězce). Po vykonání příkazu bude mít řetězcová proměnná vystup hodnotu "Vytiskneme alfa a beta.".

Při předání jiných parametrů (např. číselných hodnot) je výsledek při použití totožného formátovacího řetězce následující:

cislo1 = 4
cislo2 = -15                      # celá čísla
vystup = "Vytiskneme {} a {}.".format(cislo1, cislo2)
print(vystup)                     # => "Vytiskneme 4 a -15."
 
cislo1 = 11.869532
cislo2 = 3.856e-26                # čísla s plovoucí des. čárkou
vystup = "Vytiskneme {} a {}.".format(cislo1, cislo2)
print(vystup)                     # => "Vytiskneme 11.869532 a 3.856e-26."

Výsledky pro nás pravděpodobně nejsou nijak překvapující, ale až dosud nám pravděpodobně metoda format nepřipadá nijak převratná.

Dosazování parametrů

Sekce ohraničené složenými závorkami jsou nahrazeny parametry, které předáváme metodě format. Pořadí a formátování jednotlivých položek je určeno popisem uvnitř sekcí (který může být i prázdný jako v příkladech výše)1) . A právě v tom tkví síla a užitečnost této formátovací metody.

Popis sekce se skládá ze dvou částí oddělených dvojtečkou (např. {4:^10s}, každá z nich může být prázdná)

Přiřazení parametrů

Parametry volání metody mohou obecně být poziční a pojmenované (klíčové). Poziční parametry číslujeme (od nuly výše), na klíčové odkazujeme pomocí jejich jména. Indexy pozičních parametrů mohou být vynechány, potom jsou automaticky nahrazeny posloupností 0, 1, 2, …, tj. parametry jsou použity v pořadí dle volání metody.

# neuvedené pořadí
"Čísla {}, {} a {}.".format(1, 2, 3)       # => 'Čísla 1, 2 a 3.'
# stejný efekt pomocí posloupnosti 0, 1, 2, ...
"Čísla {0}, {1} a {2}.".format(1, 2, 3)    # => 'Čísla 1, 2 a 3.'
# pořadí ale může být i odlišné
"Čísla {2}, {1} a {0}.".format(1, 2, 3)    # => 'Čísla 3, 2 a 1.'
# některý parametr může být použit vícekrát, jiný vůbec
"Čísla {1}, {1} a {1}.".format(1, 2, 3)    # => 'Čísla 2, 2 a 2.'
 
# pojmenované parametry
"{jmeno} {prijmeni}".format(jmeno = "Jakub", prijmeni = "Krčín")
                                           # =>'Jakub Krčín'
# nezáleží na pořadí předaných pojmenovaných parametrů
"{jmeno} {prijmeni}".format(prijmeni = "Krčín", jmeno = "Jakub")
                                           # =>'Jakub Krčín'
 
# kombinace pozičního a pojmenovaného přiřazení
"{vyska} m, {1} m, {0} m".format(1.5, 2.5, vyska = 3.5)
                                           # => '3.5 m, 2.5 m, 1.5 m'
# nadbytečné parametry (poziční ani pojmenované) nejsou použity
"{vyska} m, {1} m, {0} m".format(1.5, 2.5, 4.0, vyska = 3.5, h = 0.0)
                                           # => '3.5 m, 2.5 m, 1.5 m'

Popis formátu

Za dvojtečkou (která musí být uvedena i pokud je část pro přiřazení parametrů prázdná) následuje popis toho, jaký formát požadujeme.

Popis se skládá z několika položek:

V konkrétním případě můžeme použít jen některé z nich (případně žádnou). Ne všechny kombinace dávají smysl. Jednotlivé položky budou vysvětleny níže. Není nutné si všechny možnosti pamatovat, některé kombinace v praxi použijete jen výjimečně (navíc některé speciální volby ani neuvádíme). Přesný a kompletní popis naleznete v oficiální dokumentaci jazyka.

Jednotlivé části popisu skládáme zprava doleva v uvedeném pořadí.

Typ hodnoty

V závislosti na datovém typu předaného parametru k formátování jsou dostupné tyto možnosti.

Datový typ int
d číslo v běžném tvaru (desítková soustava)
b číslo ve dvojkové (binární) soustavě
o číslo v osmičkové soustavě
x číslo v šestnáctkové (hexadecimální) soustavě
X číslo v šestnáctkové soustavě (s velkými písmeny)
c znak - číslo převedeno na znak (viz funkce chr)
neuvedeno jako d
Datový typ float
e číslo v exponenciálním tvaru (exponent oddělen e)
E číslo v exponenciálním tvaru (s použitím E)
f číslo v pevném tvaru (bez exponentu)
F jako f, ale hodnoty jako INF velkými písmeny
g podle hodnoty zvolen typ e nebo f
G podle hodnoty zvolen typ E nebo F
% hodnota vynásobena 100, zobrazena jako f a doplněna znakem procenta
neuvedeno v podstatě jako g
Datový typ str
s řetězec
neuvedeno jako s

Python má i řadu dalších typů, s některými se ještě seznámíme. Například pro komplexní čísla využijeme stejná pravidla jako pro float aplikovaná na reálnou i komplexní část. U dalších typů (např. bool či NoneType) musí být popis typu prázdný. V takovém případě je výstupem textová reprezentace hodnoty, např. True. Je možné také definovat speciální formátovací znaky pro konkrétní datový typ (typickým příkladem je formátování data a času).

Přesnost

Požadovaná přesnost u řetězců znamená počet použitých znaků řetězce, u typu int nemá smysl a u ostatních čísel znamená počet číslic za desetinnou čárkou (resp. tečkou). Číslo je zaokrouhleno na požadovaný počet desetinných míst. Uvádí se jako celé číslo za tečkou (např. .5).

Znak pro seskupení

Pro lepší čitelnost se může v zobrazení čísel použít znak , pro oddělení tisíců, miliónů atd. Podobně se může použít znak _, který navíc pro zobrazení b, o, x a X odděluje skupiny čtyř číslic. Základní chování je neoddělovat skupiny číslic.

Celková šířka

Tento parametr určuje celkový počet znaků pro formátovaný výstup. Výstup nebude nikdy kratší, pokud se však všechny znaky v požadovaném formátu do této šířky nevejdou, může být i větší. Počáteční 0 u číselných formátů znamená doplnění nulami zleva na požadovanou šíři. Není-li uvedena, použije se jen nezbytný počet znaků.

Varianta

U celých čísel v jiné než desítkové soustavě můžeme počátečním # vynutit také výstup prefixu (např. 0b pro dvojkovou soustavu).

Znaménko

U číselných typů můžeme ovlivnit výstup znaménka:

Zarovnání

Způsob zarovnání výstupního řetězce na požadovanou celkovou šířku určíme pomocí:

Pro doplnění se normálně používá znaku mezery, ale můžeme si vynutit jiný znak, pokud jej uvedeme před značkou zarovnání.

Na několika příkladech nyní ukážeme použití právě popsaných pravidel.

# parametr 'int', výstup v různých soustavách, prefix soustavy
"dec:{0:d}, bin:{0:#b}, oct:{0:#o}, hex:{0:#x}, char:{0:c}".format(65)
    # => 'dec:65, bin:0b1000001, oct:0o101, hex:0x41, char:A'
# parametr 'float' - exponenciální a pevný tvar, procenta
'{0:e}, {0:f}, {1:%}'.format(3.14, 0.215)
    # => '3.140000e+00, 3.140000, 21.500000%'
# jiné datové typy argumentů
'{}, {}'.format(True, None)                # => 'True, None'
# použití přesnosti pro 'float' a 'str'
'{0:.4f}, {0:.4E}, "{1:.4s}"'.format(1.2345678e-6, 'ABCDEFGH')
    # => '0.0000, 1.2346E-06, "ABCD"'
'{:.0f}'.format(15.412)                    # => '15' (na celá čísla)
# seskupování číslic
'{0:,f}, {1:_d}, {1:#_x}'.format(1234567.890123, 65537)
    # => '1,234,567.890123, 65_537, 0x1_0001'
# nastavení celkové šířky výstupu    
'*{0:10d}*, *{1:10s}*, *{1:4s}*'.format(713, "ABCDEF")
    # => '*       713*, *ABCDEF    *, *ABCDEF*'
# doplnění čísla nulami zleva, zaokrouhlení    
'{:012.4f}'.format(-4.1279999)             # => '-000004.1280'
# znaménko
'*{0:+f}*, *{1:+f}*'.format(2.718, -2.718) # => '*+2.718000*, *-2.718000*'
'*{0:-f}*, *{1:-f}*'.format(2.718, -2.718) # => '*2.718000*, *-2.718000*'
'*{0: f}*, *{1: f}*'.format(2.718, -2.718) # => '* 2.718000*, *-2.718000*'
# zarovnání
'*{:<10}*{:^10}*{:>10}*'.format('vlevo', 'na střed', 'vpravo')
    # => '*vlevo     * na střed *    vpravo*'
# zarovnání s použitím definovaného znaku
'{:_^12d}'.format(729)                     # => '____729_____'
 
# příklady s více položkami zároveň
'{:_<+15,.1f}'.format(7005.765)            # => '+7,005.8_______'
'{:*^12.4s}'.format('ABCDEF')              # => '****ABCD****'
1)
Pozorný čtenář se bude hned zajímat o to, jak zabezpečit výstup znaků složených závorek. Provede se to zdvojením požadovaného znaku, tj. pomocí {{ a }}. Například množinu zapíšeme následovně:
'Množina {{1, 2, {}}}'.format(3) # => 'Množina {1, 2, 3}'