print()
– pravděpodobně nejpoužívanější funkce Python'u. A to nejen pro výstup na konzoli. Její syntaxe jest:
sys.stdout.flush()
).
Výchozí nastavení mimo jiné znamená, že prázdný print() jednoduše odřádkuje:
Kombinace všech nastavení:
print TEXT,
.
Přesměrování výstupu:
print >> sys.stderr, TEXT
.
print() se pokusí vyhodnotit jako tisknutelný řetězec prakticky cokoliv, co mu předhodíte (podobně jako str()). Mimo jiné to znamená, že pokud není vstupní řetězec označen jako raw (tedy r""
), budou v něm vyhodnoceny všechny tzv. escape characters, včetně číselných referencí na znaky:
hexadecimálně | speciální \-notace | význam |
---|---|---|
0x07 | \a |
zvonek, bell, alert |
0x08 | \b |
backspace |
0x09 | \t |
tabulátor (horizontální) |
0x0a | \n |
odřádkování, newline |
0x0b | \v |
vertikální tabulátor |
0x0c | \f |
formfeed |
0x0d | \r |
carriage return |
\\ |
zpětné lomítko, backslash | |
\' |
jednoduchá uvozovka | |
\" |
dvojtá uvozovka | |
\nnn |
oktalová notace, n ∈ {0..7} |
|
\xnn |
hexadecimální notace, n ∈ {0..9, a..f, A..F} |
|
\N{alias} |
unicodový znak jména alias | |
\uxxxx |
unicodový znak s 16ti bitovou hodnotou xxxx | |
\Uxxxxxxxx |
unicodový znak s 32ti bitovou hodnotou xxxxxxxx |
PS: Prakticky to znamená, že na terminálech, které to podporují, můžete třeba zapípat pomocí print(chr(7))
nebo mazat předchozí napsaný text pomocí print(chr(8))
^_~
Počínaje Python'em 3.6, máme k dispozici velmi jednoduché a mocné formátování pomocí tak zvaných f-řetězců (tedy pochopitelně formátovaných řetězců). Prakticky ve všech ohledech se chová jako starší formátování pomocí funkce format() (viz níže), jen je výrazně přehlednější:
Co se metody format()
týká, je ji možno použít jak pozičně, tak za pomoci pojmenovaných argumentů (což je ukecanější, ale může to být v některých situacích přehlednější). Jejím hlavním úkolem je snadné předávání hodnot složených objektů:
format()
je však mnohem mocnější – jako parametr do {}
můžete totiž poslat prakticky cokoliv (seznam, slovník, instanci třídy...) a celkem rozumně s tím pak pracovat.
Starší způsob formátování, dosud podporovaný, ale teoreticky určený k (pravděpodobnému) vyřazení, vypadá pro srovnání takto:
'%s' % msg
selže, není-li proměnná msg jednoduchý typ, protože se ji pokusí rozdělit na prvky, které pak ale nebude mít kam přiřadit. Opraví to zápis s explicitní n-ticí '%s' % (msg, )
(byť má samozřejmě své mouchy), ale myslete na to, že.
V principu tento nový formátovací minijazyk říká:
{CO:JAK}
Část CO je jednoduchá – odkazovaný (ať už pořadím nebo jménem) objekt, který bude převeden na řetězec. Část JAK je složitá (byť by měla hodně odpovídat starší céčkovské konvenci), obsluhuje především výpis čísel a radši uvedu rovnou definici z dokumentace:
format_spec ::= [[fill]align][sign][#][0][width][grouping_option][.precision][type] fill ::= <any character> align ::= "<" | ">" | "=" | "^" sign ::= "+" | "-" | " " width ::= digit+ grouping_option ::= "_" | "," precision ::= digit+ type ::= "b"|"c"|"d"|"e"|"E"|"f"|"F"|"g"|"G"|"n"|"o"|"s"|"x"|"X"|"%"
Zleva doprava se tedy mohou vyskytnout následující formátovací a zobrazovací prvky:
<
pro zarovnání doleva, >
doprava, ^
na střed a =
pro výplň mezi znaménkem čísla a vlastním číslem);
+
tiskne vždy plus i mínus, -
pouze mínus, mezera tiskne mínus a místo plusu mezeru);
#
způsobí konverzi čísla plus zobrazení identifikátoru číselné soustavy*, znak 0
na tomto místě v podstatě odpovídá zarovnání nulou 0=
na začátku;
,
nebo _
);
eEfFgG%
) je to solidní masakr. Pro řetězce tam nemusíte psát nic (nebo s
).
PS: Pro podrobnosti se podívejte na originální specifikaci a příklady.
Zajímavou vlastností formátování je, že je můžete zanořovat do sebe. Příklad bude asi výmluvnější:
Vidíme tedy, že formátovací závorky můžeme zanořovat a tudíž je použít i pro předávání doplňkových údajů formátování (zde počet znaků k zacentrování).
Starší* způsob formátování je obšlehnutý z Céčka, z jeho funkce sprintf().
b''
, kde vlastně fungovalo celý dvojkový Python a fungovat přestalo až s příchodem Python'u trojkového, tomu asi učinilo s konečnou platností přítrž.
Jeho modifikátory typu jsou skoro stejné jako u klasického formátování, ale vlastní zápis je úplně jiný:
format_spec ::= %[(mapkey)][flag][width][.precision][length]type mapkey ::= <any character> flag ::= "#" | "0" | "-" | " " | "+" width ::= digit+ | "*" precision ::= digit+ | "*" length ::= "h" | "l" | "L" type ::= "d"|"i"|"o"|"u"|"x"|"X"|"e"|"E"|"f"|"F"|"g"|"G"|"c"|"r"|"s"|"a"|"%"
Přitom pole length nemá v Python'u žádný význam (takže není důvod ho používat), flag se nechová úplně jako u f'' (např. -
je zarovnání vlevo) a type má ke každému typu hromadu doplňujících poznámek. Nehledě na to, že *
v šířce nebo přesnosti zcela změní výchozí vyhodnocení předávaných parametrů:
PS: Podrobnosti konzultujte s originální dokumentací.
Metoda format() je obzvláště mocná ve spojení s pythoními víceřádkovými řetězci – snadno tak můžete připravit řetězcové šablony, které později „nakrmíte“ vhodnými parametry a vytisknete. Příklad:
Pro vytváření a používání šablon je k dispozici ještě specializovaný nástroj v podobě třídy string.Template. Ta umožňuje zaměňovat pojmenované identifikátory $identifikátor
za odpovídající hodnoty z mapování:
$identifikátor
, který nemůže být částí validního pythonovského jména objektu, ukončuje jméno identifikátoru. Proto je-li třeba spojit identifikátor s dalším řetězcem, vkládá se identifikátor do znaků {}
(tady to tedy zrovna není potřeba).
Ač se na první pohled chová prakticky úplně stejně jako format() (samozřejmě minus příslušný minijazyk), její výhodou je to, že si z ní můžete vytvořit vlastní odvozené třídy, ve kterých zcela přepíšete způsob zápisu a vyhodnocování šablony.
ANSI Escape sequences (codes) jsou speciální řídicí sekvence (uvozené dvěma znaky \033[
– to první je oktalová reference pro znak Escape, tedy 338 = 1b16 = 2710
), které signalizují terminálu:
Na terminálech, které je podporují, pak můžete třeba tisknout tučně..
1m
zapíná tučné písmo, sekvence 0m
vrací tisk do původního stavu.
..nebo barevně:
31m
zapíná červené písmo, sekvence 0m
opět vrací tisk do původního stavu.
PS: Jako na potvoru terminál ve Windows jako jeden z mála těmto sekvencím vůbec nerozumí. Naštěstí instalace např. ANSICON'u Jasona Hooda to napraví.
sekvence | význam | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
\033[nA \033[nB \033[nC \033[nD |
posun kurzoru o n znaků nahoru, dolů, dopředu, dozadu | ||||||||||||||||||||||||||||||||||||||||||||||||||
\033[řádek;sloupecH \033[řádek;sloupecf |
přesun kurzoru na pozici řádek,sloupec (bez udání souřadnic do levého horního rohu) | ||||||||||||||||||||||||||||||||||||||||||||||||||
\033[s \033[u |
∙ uložení aktuální pozice kurzoru ∙ vrácení kurzoru na uloženou pozici |
||||||||||||||||||||||||||||||||||||||||||||||||||
\033[nS \033[nT |
posun displeje (scroll) o n řádek nahoru/dolů | ||||||||||||||||||||||||||||||||||||||||||||||||||
\033[nJ |
Smazání displeje: ∙ bez čísla nebo s 0 od kurzoru na konec; ∙ s 1 od kurzoru na začátek; ∙ s 2 smaže celý displej (a občas i přesun na souřadnice [0,0], tj. levý horní roh). |
||||||||||||||||||||||||||||||||||||||||||||||||||
\033[nK |
Smazání řádku: ∙ bez čísla nebo s 0 od kurzoru na konec; ∙ s 1 od kurzoru na začátek; ∙ s 2 smaže celý řádek. (Pozice kurzoru se nemění.) |
||||||||||||||||||||||||||||||||||||||||||||||||||
\033[?25l \033[?25h |
schování/ukázání kurzoru | ||||||||||||||||||||||||||||||||||||||||||||||||||
\033[nm \033[n;nm \033[n;n;nm \033[n;…;nm |
Nastavení efektů výpisu podle následujících kódů n ([] značí reset příslušného nastavení):
Barvy podle ISO 6429:
|
Možnosti těchto sekvencí jsou však podstatně větší – podívejte se na dokumentaci. Samozřejmě ne každý terminál podporuje všechno, tak pozor na to!
Jelikož přinejmenším barvy se na terminálovém výstupu dost často hodí, existuje mnoho modulů, které řeší, že to na většině Windows použít nejde, namátkou třebas colorama.
A kdo nechce tahat do svých programů externí závislosti a vystačí si jenom s barvami, třeba použije následující pomůcku ze Stack Overflow:
Na závěr ještě jedna třešnička na dortu. Funkce get_terminal_size() vrací velikost aktuálního terminálového okna, ve kterém jste spustili příslušný skript, a to v podobě podtřídy n-tice, takže příslušné údaje můžete snadno vytáhnout následujícím způsobem:
Tato funkce ve skutečnosti způsobí následující posloupnost kroků:
(80, 24)
.
shutil.get_terminal_size(fallback=(columns, lines))
Většinou to funguje docela dobře, ale terminály a vůbec jednotlivá prostředí se tak liší, že úplně se na to spoléhat nedá.