Knyga/Spausdinimas ir formatavimas
Ką išmoksi šiame skyriuje?
- Kaip naudoti
f-tekstines eilutesPython kalboje - Kaip formatuoti skaičius, tekstą ir atlikti lygiavimą
- Kaip naudoti
.format()metodą - Kaip veikia senasis formatavimas su
%simboliu - Kaip naudoti
Templateklasę saugesniam formatavimui - Kada naudoti
safe_substitute()vietojesubstitute() - Kaip tekstų formatavimas padeda sumažinti kodo kiekį ir padidina aiškumą
Spausdinimas ir formatavimas
Standartinis tekstinės eilutės išvedimas į terminalą dažnai nėra pakankamas - įsivaizduok situaciją:
Benas nori, kad programa išspausdintų jam darbuotojų ir jų atliekamų pareigų sąrašą. Tekstas turėtų atrodyti maždaug taip: “Darbuotojas Jonas yra programuotojas”
Iš pirmo žvilgsnio, užduotis atrodo paprasta – reikia išspausdinti teksto eilutę:
print(“Darbuotojas Jonas yra programuotojas”)
Jeigu Benas turi du darbuotojus, programos kodas atrodytų maždaug taip:
print(“Darbuotojas Jonas yra programuotojas”) print(“Darbuotojas Antanas yra buhalteris”)
Kaip ir viskas gerai, bet ką daryti tuo atveju, jeigu Benas turi 100 darbuotojų? 100 kodo eilučių spausdinančių kiekvieno darbuotojo vardą ir pareigas, kurias reikia suvesti ranka? Programa nelogiška, nes tokiu atveju Benas gali tiesiog ant lapo ranka susirašyti darbuotojus ir nereik jokio Pitono. Tai kaip išspręsti šią problemą? Pitonas turi atsakymą.
Kaip ir dauguma programavimo kalbų, Pitonas turi tekstinių eilučių formatavimą. Formatuotina tekstinė eilutė (angliškai - "String literal"), tai dinaminė tekstinė eilutė, kuri priima kintamuosius, o spausdinant tokią eilutę į terminalą, ji išveda kintamųjų reikšmes, pavyzdžiui:
vardas = "Jonas"
print(f"Mano vardas yra {vardas}")
Šis kodas į terminalą išves tekstinę eilutę:
Mano vardas yra Jonas
Pitone yra keturi būdai, kaip galima formatuoti tekstines eilutes:
- F-tekstinė eilutė (f-strings).
- str.format() metodas.
- Formatavimas naudojant % simbolį.
- Formatavimas naudojant šablonines tekstines eilutes (template strings)
F-tekstinė eilutė
F-tekstinės eilutės pitone atsirado kartu su 3.6 versija. Tai yra vienas iš paprasčiausių ir lengviausiai skaitomų būdų formatuoti tekstines eilutes. F-tekstinės eilutės leidžia programuotojui tiesiogiai įtraukti išsireiškimus (angliškai - expressions) bei kintamuosius naudojant riestinius skliaustus (“{ }”).
Pagrindiniai šio būdo privalumai:
- Tekstinėje eilutėje galima rašyti išsireiškimus bei kintamuosius, naudojant vietaženklius (angliškai - placeholder).
- Yra galimybė formatuoti skirtingus tipus - skaičius, datas bei tekstines eilutes, nustatant jų tikslumą ir lygiavimą.
F-tekstinė eilutė žymima raide “f”, kuri yra rašoma prieš tekstinę eilutę indikuojančias kabutes – f"tekstinė eilutė". Kintamųjų pavadinimai tokioje eilutėje yra įrašomi į riestinius skliaustus, pvz.:
vardas = "Ieva"
amžius = 25
print(f"Mano vardas yra {vardas} ir man yra {amžius} metai.")
Šis kodas į terminalą išves tekstinę eilutę:
Mano vardas yra Ieva ir man yra 25 metai.
Kaip matai, Pitonas automatiškai į vietaženklių su kintamųjų pavadinimais vietas įrašė kintamųjų reikšmes. Paminėtina ir tai, kad F-tekstinėje eilutėje gali būti naudojami išsireiškimai, juos įrašant į riestinius skliaustus, pvz.:
amžius = 25
print(f"Kitais metais man sueis {amžius + 1} metai.")
Šis kodas į terminalą išves tekstinę eilutę:
Kitais metais man sueis 26 metai.
Šiuo atveju, Pitonas paėmė kintamąjį amžius ir prie jo pridėjo vienetą (25 + 1 = 26). Galimybė naudoti tokius paprastus išsireiškimus palengvina programuotojo darbą, kadangi nereikia atlikti šių veiksmų iki išvedant tekstinę eilutę į terminalą ar saugant ją faile.
F-tekstinėje eilutėje galima atlikti skaičių formatavimą. Tai yra ypač naudingas funkcionalumas, kadangi programuotojui nereikia atlikti papildomų veiksmų, kaip, kad saugoti naują kintamąjį su suformatuota reikšme ir pan. F-tekstinėje eilutėje tai užrašoma tokiu būdu:
pi = 3.14159
print(f"Skaičiaus PI vertė yra: {pi:.2f}")
“:.2f” išsireiškimas indikuoja, kiek skaičių po kablelio rodyti - “:” (dvitaškis) nurodo formatavimo instrukcijos pradžią, “.2” rodo, kiek skaičių po kablelio bus rodoma, “f” indikuoja, kad tai yra dešimtainis skaičius. Tokia tekstinė eilutė į terminalą išves:
Skaičiaus PI vertė yra 3.14”
Kaip matai, tekstinė eilutė pati nukirpo paskutinius tris skaičius po kablelio ir paliko tik du.
Pitonas taip pat suteikia galimybę F-tekstinėje eilutėje lygiuoti tekstą. Kaip ir formatuojant skaičius, “:” (dvitaškis) nurodo formatavimo instrukcijos pradžią, “<” nurodo, jog bus lygiuojama kairėje pusėje, “>” nurodo lygiavimą dešinėje, o “^” - centre. Lygiavimas šiuo atveju yra suprantamas tekstinės eilutės kontekste, o ne ekrano, puslapio ar pan. Išraiška “:<10”, reiškia, kad bus taikomas lygiavimas iš kairės, o viso kintamojo ilgis bus 10 simbolių. Taip pat, galima nurodyti, kuo bus užpildomi tušti tarpai, pvz., “:.<10”., “.” einantis po dvitaškio ir prieš “mažiau” ženklą, indikuoja, kad tušti tarpai bus užpildyti taškais. Atrodo gana painiai, bet pažiūrėk, kaip tai atrodo, kai kodą apdoroja pitonas:
vertė = 20
print(f"Lygiuojama kairėje: {vertė:<10}")
print(f"Lygiuojama dešinėje: {vertė:>10}")
print(f"Lygiuojama centre: {vertė:^10}")
Šis kodas terminale išves tokias tekstines eilutes:
Lygiuojama kairėje: 20 Lygiuojama dešinėje: 20 Lygiuojama centre: 20
Kaip matai, skaičius 20 yra atvaizduojamas skirtingose vietose, pirmoje eilutėje - kairėje, antroje - dešinėje, trečioje centre. Mes nematome, bet viskas, kas yra po teksto, yra sudėta į 10 simbolių, iš kurių matome tik du – 20 arba “2” ir “0”.
Pažiūrėk, kaip tas pats kodas atrodytų, jeigu tarpus užpildytume taškais:
vertė = 20
print(f"Lygiuojama kairėje: {vertė:.<10}")
print(f"Lygiuojama dešinėje: {vertė:.>10}")
print(f"Lygiuojama centre: {vertė:.^10}")
Šis kodas išves terminale tokias tekstines eilutes:
Lygiuojama kairėje: 20........ Lygiuojama dešinėje: ........20 Lygiuojama centre: ....20....
Kaip matai, į formatavimo sakinį pridėjus “.”, visi tušti tarpai buvo užpildyti taškais. Dabar labai aiškiai matome, kaip veikia vertės lygiavimas – prie tekstinės eilutės yra pridedama 10 simbolių, o vertė yra judinama tarp tų simbolių - į pradžią, į pabaigą arba per vidurį.
F-tekstinės eilutės yra moderniausias ir paprasčiausias būdas formatuoti tekstą bei kintamuosius prieš juos išvedant į terminalą, tačiau šis būdas veikia tik su pitono 3.6 ir vėlesnėmis versijomis. Nepaisant to, yra rekomenduojama naudoti šį tekstinių eilučių formatavimo būdą, o ne kitus, senesnius būdus.
Tekstinės eilutės formatavimas naudojant str.format() metodą
Šis metodas atsirado pitono 3 versijoje, jis naujoja riestinius skliaustus kaip vietaženklius, kuriuos išvesties metu užpildo kintamųjų reikšmėmis. Gilinantis pastebėsi, kad šis būdas yra panašus į f-tekstinę eilutę - naudojama ta pati sintaksė, tad nebus sudėtinga suprasti veikimą.
Metodas format() yra kviečiamas tiesiai iš tekstinės eilutės, pvz.:
"Sveikas, pasauli! ".format()
Naudojant .format() metodą dinaminės tekstinės eilutės dalys yra nurodomos riestiniuose skliaustuose, pvz.:
"Sveikas, {}!"
Norint vietoje skliaustų matyti reikšmę, ją paduodame kaip kintamąjį .format() metodui:
"Sveikas, {}!".format("pasauli")
Svarbu paminėti tai, jog tuo atveju, kai yra kelios dinaminės dalys, t. y. tekstinėje eilutėje yra keli riestiniai skliaustai, pvz., "{}, {}!", tai .format() metodui reikšmės yra paduodamos viena paskui kitą, iš kairės į dešinę:
"{}, {}".format("Sveikas", "pasauli")
format() metodui mes galime paduoti ir kintamuosius, vadovaujantis jau prieš tai aptartu eiliškumu:
vardas = "Ieva"
amžius = 25
print("Mano vardas yra {} ir man yra {} metai.".format(vardas, amžius))
Šis kodas į terminalą išves tekstinę eilutę:
Mano vardas yra Ieva ir man yra 25 metai.
Format() metodui paduoti parametrai gali būti pernaudojami tekstinėje eilutėje, pvz.:
“{0} yra {1}. {0} yra {2}.".format("Dangus", "mėlynas", "beribis")
Išvestas tekstas terminale:
Dangus yra mėlynas. Dangus yra beribis.
Kaip matai, riestiniuose skliaustuose galime nurodyti parametro poziciją format() metodui perduotų parametrų sąraše. Tokiu būdu yra pernaudojamos reikšmės ir sumažinamas kodo kiekis.
Skaičių bei lygiavimo formatavimas, iš principo veikia identiškai, kaip ir f-tekstinėje-eilutėje, tiesiog formatavimo taisykles paduodame į riestinius skliaustus:
# Skaičiaus su kableliu formatavimas
pi = 3.14159
print("Skaičiaus PI vertė yra: {:.2f}".format(pi))
# Lygiavimo formatavimas
vertė = 20
print("Lygiuojama kairėje: {:.<10}".format(vertė))
print("Lygiuojama dešinėje: {:.>10}".format(vertė))
print("Lygiuojama centre: {:.^10}".format(vertė))
Šis kodas išves terminale tokias tekstines eilutes:
Skaičiaus PI vertė yra 3.14. Lygiuojama kairėje: 20........ Lygiuojama dešinėje: ........20 Lygiuojama centre: ....20....
Kaip matai, iš principo str.format() metodas veikia labai panašiai, kaip ir f-tekstinės eilutės, tik užrašymas yra sunkiau skaitomas ir ilgesnis.
Tekstinės eilutės formatavimas naudojant % ženklą
Tekstinės eilutės formatavimas naudojant % ženklą yra seniausias būdas Pitone formatuoti tekstines eilutes. Šiais laikais jo naudojimas yra nerekomenduotinas, kadangi Pitonas 3-oje ir vėlesnėse versijose sudarė galimybę naudoti daug paprasčiau skaitomas ir turinčias daug daugiau galimybių f-tekstines eilutes ir metodą str.format(). Su šiuo būdu supažindiname, nes jo naudojimą vis dar galime sutikti senose programose, kurios naudoja ankstesnę Pitono versiją (senesnę nei 3.0).
Šis būdas, kaip ir ankstesni, yra paremtas vietaženkliais, tačiau šiuo atveju, vietaženklis turi indikuoti, kokio tipo vertė bus įdėta į jo vietą, t. y. turi nurodyti duomenų tipą:
- “%s” - s indikuoja, kad bus naudojamas tekstinės eilutės tipo kintamasis
- “%d” - d indikuoja, kad bus naudojamas skaičiaus tipo kintamasis
- “%f” - f indikuoja, kad bus naudojamas dešimtainio skaičiaus tipo kintamasis
Kode šie vietaženkliai panaudojami tokiu būdu:
print("Mano vardas yra %s ir man yra %d metai." % ("Ieva", 25))
//Skaičiaus su kableliu formatavimas
pi = 3.14159
print("Skaičiaus PI vertė yra: %.2f" % pi)
Kaip matai, pats kodas yra žymiai sunkiau skaitomas, kintamųjų padavimas sudėtingesnis ir daug sunkiau naudoti, jeigu reikia naudoti daugiau nei kelis parametrus. Paminėtina ir tai, kad šis būdas turi daug mažiau galimybių, pvz., neturi galimybės formatuoti lygiavimą ir pan.
Formatavimas naudojant šablonines tekstines eilutes (template strings)
Šabloninių tekstinių eilučių funkcionalumą suteikia string modelio Template klasė. Ši klasė suteikia saugią alternatyvą tekstinių eilučių formatavimui. Šis būdas yra naudingas tais atvejais, kai nėra pasitikima vartotojo įvestimi, kadangi padeda išvengti kodo įskiepio. Norint naudoti šį būdą, reikia susiimportuoti Template klasę iš string modelio:
from string import Template
Norint naudoti template modelį, mes sukuriame template objektą, kurio konstruktoriuje nurodom tekstinės eilutės šabloną. Dinaminės tekstinės eilutės dalys yra indikuojamos “$” ženkliuku ir kintamojo pavadinimu. Norint dinaminio kintamojo vietoje nurodyti vertę, kviečiame objekto metodą substitute(), kurio parametruose nurodome dinaminio kintamojo pavadinimą ir priskiriam jam vertę:
from string import Template
šablonas = Template("Mano vardas yra $vardas.")
print(šablonas.substitute(vardas="Ieva"))Šis kodas išves tekstinę eilutę:
Mano vardas yra Ieva
Šablono dinaminiems kintamiesiems gali būti priskirti kintamieji, ne tik tiesioginės reikšmės:
from string import Template
šablonas = Template("Mano vardas yra $vardas ir man yra $amzius metai")
vardas = "Ieva"
amžius = 25
print(šablonas.substitute(vardas=vardas, amzius=amžius))
Šis kodas išves tekstinę eilutę:
Mano vardas yra Ieva ir man yra 25 metai.
Paminėtina tai, kad substitute() metodas išmes klaidą, jeigu nepaduosime visų dinaminių parametrų verčių. Tam, kad išvengti šios klaidos, galime naudoti safe_substitute() metodą, kuris ignoruoja trūkstamas vertes ir slopina klaidos pranešimus:
from string import Template
šablonas = Template("Mano vardas yra $vardas ir man yra $amzius metai ")
vardas = "Ieva"
amžius = 25
print(šablonas.safe_substitute(vardas=vardas))
Šis kodas išves tekstinę eilutę:
Mano vardas yra Ieva ir man yra $amzius metai.
Atkreipk dėmesį, kad šabloninės eilutės kintamieji, negali būti su lietuviškomis raidėmis, Pitono kompiliatorius gali nesuprasti lietuviškų raidžių kintamųjų varduose ir jį tiesiog pavers tekstinės eilutės dalimi.
Šabloninė tekstinė eilutė yra paprastas ir saugus būdas priimti ir išvesti vartotojo įvestį, bet jis nėra toks modernus, kaip f-tekstinės eilutės ar .format() metodas, ir negali atlikti sudėtingesnių formatavimo užduočių, pvz., lygiavimo.
Taigi, kaip matai yra įvairų būdų, kuriuos galime pasitelkti tekstinės eilutės formatavimui. Prisimink temos pradžioje minėtą Beną ir jo problemą su darbuotojų ir jų pareigų išspausdinimu. Perskaitęs šį skyrių matai, kad Benui nereikėtų šimtą kartų ranka rašyti tekstines eilutes, o pasitelkti tekstinės eilutės formatavimą. Beno darbuotojai sudėti į žodyną (angliškai - dictionary), tad juos išspausdinti terminale gali tokiu būdu:
darbuotojai = [
{"vardas": "Jonas", "pareigos": "programuotojas"},
{"vardas": "Petras", "pareigos": "buhalteris"},
{"vardas": "Ieva", "pareigos": "dizainerė"}
]
for darbuotojas in darbuotojai:
print(f"{darbuotojas['vardas']} yra {darbuotojas['pareigos']}")
Ši programa terminale išspausdins visus žodyne esančius darbuotojus ir jų pareigas:
Jonas yra programuotojas Petras yra buhalteris Ieva yra dizainerė
Kaip matai, pasitelkdami f-tekstinę eilutę, Beno problemą mes išsprendėme dviem kodo eilutėmis - iteruojame per žodyną naudodami for ciklą ir išspausdinam žodyne saugomą informaciją apie darbuotojus. Formatuotinos tekstinės eilutės labai palengvina darbą su duomenų išvedimu ar įrašymu į failą, kadangi leidžia dinamiškai pakeisti tam tikras tekstinės eilutės vietas, nurodyti skaičiaus formatą ir atlikti panašius veiksmus tiesiogiai tekstinėje eilutėje. Tokia galimybė sumažina kodo kiekį ir daro kodą lengviau suprantamą, nes nereikia skaityti 20 eilučių kodo, aprašančio dešimtainio skaičiaus skaitmenų po kablelio apribojimą iki dviejų.