Kirjoittaminen tiedostoon

Jos ohjelman halutaan kirjoittavan tiedostoon, avataan tiedosto muuten samalla tavalla kuin tiedostosta lukiessa, mutta käsittelytapana on nyt joko "w" tai "a". Näiden kahden käsittelytavan ero on siinä, että "w" (englannin sanasta write) kirjoittaa mahdollisen vanhan samannimisen tiedoston päälle (vanhan tiedoston sisältö häviää siis kokonaan, vaikka vanha tiedosto olisi pitempi kuin kirjoitettava uusi teksti), kun taas "a" (englannin sanasta append) säilyttää avattavassa tiedostossa mahdollisesti jo olevan tekstin ja kirjoittaa tiedoston loppuun. Jos annetun nimistä tiedostoa ei vielä ole, se luodaan avaamisen yhteydessä.

Esimerkiksi

tulostiedosto = open("tekstia.txt", "w")

avaa kirjoittamista varten tiedoston, jonka nimi on tekstia.txt. Tiedoston mahdollinen vanha sisältö häviää avaamisen yhteydessä. Ohjelmassa voidaan tämän jälkeen käsitellä avattua tiedostoa muuttujan tulostiedosto avulla.

Avattuun tiedostoon voidaan tulostaa merkkijonoja metodin write avulla. Metodi ei lisää rivinvaihtomerkkiä tulostettavan merkkijonon loppuun, vaan lisäys pitää tehdä itse, esimerkiksi:

tulostiedosto.write("Ensimmainen rivi\n")

Metodilla write voi tulostaa vain merkkijonoja. Jos tiedostoon halutaan tallentaa esimerkiksi lukuja, pitää ne ensin muuttaa merkkijonoiksi. Tämä voidaan tehdä esimerkiksi käyttämällä tulostuksen muotoilua:

kanta = 3.5
ekspo = 5
tulos = kanta ** ekspo
tulostiedosto.write(f"{kanta:.2f} potenssiin {ekspo:d} on {tulos:.2f}\n")

Toinen vaihtoehto on muuttaa tulostettavat luvut ensin merkkijonoiksi str-operaattorilla. Jos samalle riville tulostettava teksti koostuu useammasta osasta, voidaan osat yhdistää pidemmäksi merkkijonoksi +-operaattorilla:

kanta = 3.5
ekspo = 7
tulos = kanta ** ekspo
tulostiedosto.write(str(kanta) + " potenssiin " + str(ekspo) + " on " + \
                    str(tulos) + "\n")

Tällöin desimaaliluvut tulostuvat Pythonin käyttämällä oletustarkkuudella, kun taas tulostuksen muotoilua käytettäessä ohjelmoija määrää käytettävän tarkkuuden.

Kun halutut tiedot on tulostettu tiedostoon, on tiedosto suljettava close-metodilla. Tiedostoa ei ole syytä yrittää lukea ennen kuin tiedosto on suljettu. Tehokkuussyistä write-käskyjä suoritettaessa tulostamista ei tehdä itse tiedostoon välttämättä heti jokaisen write-käskyn jälkeen, vaan kirjoitettavaa dataa kerätään ensin keskusmuistissa olevaan puskuriin, jonka sisältö siirretään itse tiedostoon suurempina osina. Ennen close-metodin suorittamista tulostettu tieto ei vielä välttämättä ole itse tiedostossa, vaan vasta puskurissa, eikä se näy, jos tiedostoa yrittää lukea jollain tavalla.

Seuraava esimerkkiohjelma tulostaa edellisen kappaleen esimerkissä käytetyn vieraslistan tiedostoon. Ohjelma pyytää ensin käyttäjältä tiedoston nimen ja sen jälkeen tiedostoon kirjoitettavat nimet. Nimet tulostetaan tiedostoon rivi kerrallaan.

def main():
    print("Ohjelma kirjoittaa vieraslistan haluamaasi tiedostoon.")
    nimi = input("Anna kirjoitettavan tiedoston nimi: ")
    try:
        tulostiedosto = open(nimi, "w")
        print("Anna tallennettavat nimet.")
        print("Lopeta tyhjalla rivilla.")
        rivi = input()
        while rivi != "":
            tulostiedosto.write(rivi + "\n")
            rivi = input()
        tulostiedosto.close()
        print("Nimet on kirjoitettu tiedostoon", nimi)
    except OSError:
        print("Virhe tiedoston", nimi, "kirjoittamisessa. Ohjelma paattyy.")


main()

Alla esimerkki ohjelman suorituksesta.

Ohjelma kirjoittaa vieraslistan haluamaasi tiedostoon.
Anna kirjoitettavan tiedoston nimi: vieraat.txt
Anna tallennettavat nimet.
Lopeta tyhjalla rivilla.
Aku Ankka
Roope Ankka
Minni Hiiri

Nimet on kirjoitettu tiedostoon vieraat.txt

Toinen esimerkkiohjelma havainnollistaa lukuarvojen tulostamista tiedostoon. Ohjelma pyytää käyttäjältä ympyröiden säteitä ja kirjoittaa tiedostoon säteen sekä ympyrän pinta-alan aina samalle riville. Ohjelmassa on käsitelty poikkeusten avulla myös se virhetilanne, että käyttäjä antaa kelvottoman luvun. Tällöin ohjelman suoritusta ei kuitenkaan keskeytetä, vaan ohjelma jatkaa lukemalla käyttäjältä seuraavan luvun.

Ohjelmassa on käytetty Pythonin valmiissa math-moduulissa määriteltyä vakiota pi. Moduuli saadaan käyttöön kirjoittamalla ohjelmatiedoston alkuun import math. Tämän jälkeen moduulin funktioita ja vakioita voi käyttää math.-etuliitteen avulla, esimerkiksi math.pi.

import math

def main():
    print("Ohjelma laskee ympyroiden pinta-aloja ja tallentaa ")
    print("ne tiedostoon.")
    nimi = input("Anna kirjoitettavan tiedoston nimi: ")
    try:
        tulostiedosto = open(nimi, "w")
        tulostiedosto.write("sade    pinta-ala\n")
        print("Anna ympyroiden sateet, lopeta negatiivisella.")
        sade = 0.0     # alkuarvo while-kaskyn ehtoa varten
        while sade >= 0.0:
            rivi = input()
            try:
                sade = float(rivi)
                if sade >= 0.0:
                    pinta_ala = math.pi * sade * sade
                    tulostiedosto.write(f"{sade:<7.2f} {pinta_ala:<10.2f}\n")
            except ValueError:
                print("Virhe: sateen pitaa olla desimaaliluku.")
        tulostiedosto.close()
        print("Tulokset on kirjoitettu tiedostoon", nimi)
    except OSError:
        print("Virhe tiedoston", nimi, "kirjoittamisessa. Ohjelma paattyy.")


main()

Seuraavana on esimerkki ohjelman suorituksesta.

Ohjelma laskee ympyroiden pinta-aloja ja tallentaa
ne tiedostoon.
Anna kirjoitettavan tiedoston nimi: ympyrat.txt
Anna ympyroiden sateet, lopeta negatiivisella.
14.50
suuri
Virhe: sateen pitaa olla desimaaliluku.
pieni
Virhe: sateen pitaa olla desimaaliluku.
3.80
11.00
0.0
7.25
-1
Tulokset on kirjoitettu tiedostoon ympyrat.txt

Tiedoston ympyrat.txt sisältö on tämän jälkeen seuraava:

sade    pinta-ala
14.50   660.52
3.80    45.36
11.00   380.13
0.00    0.00
7.25    165.13