Python Vadovėlis/Failų tvarkymas

Iš wiki.angis.net.
Jump to navigation Jump to search
 ← Daugiau apie tekstines eilutes Turinys Siekiant tobulumo → 


Failų įvestis/išvestis

Štai paprastas failo įvesties ir išvesties (I/O, ang. Input/Output) pavyzdys:

# Rašyti į failą
with open("testas.txt", "wt") as rašomas_failas:
    rašomas_failas.write("Šis tekstas bus išsiųstas į failą\nPažiūrėk ir pamatysi!")

# Skaityti failą
with open("testas.txt", "rt") as skaitomas_failas:
    tekstas = skaitomas_failas.read()

print(tekstas)

Failo testas.txt išvestis ir turinys yra:

Šis tekstas bus išsiųstas į failą
Pažiūrėk ir pamatysi!

Atkreipk dėmesį, kad programa sukūrė failą pavadinimu testas.txt kataloge, iš kurio paleidai programą. Eilutėje esantis \n nurodo Python'ui toje vietoje peršokti į naują eilutę.

Apžvelkime visus veiksmus su failais:

  • Gauk failo objektą su funkcija open
  • Skaityk iš arba rašyk į failo objektą (priklausomai nuo to, kokiu režimu jis buvo atidarytas)
  • Jeigu failui atidaryti nenaudojai funkcijos with, turėsi jį uždaryti rankiniu būdu

Pirmas žingsnis yra gauti failo objektą. Tai galima padaryti naudojant funkciją open. Formatas yra failo_objektas = open(failo_pavadinimas, režimas), kur failo_objektas yra kintamasis, į kurį reikia įdėti failo objektą, failo_pavadinimas yra eilutė su failo pavadinimu, o režimas yra "rt", kad (ang. read) skaityti failą kaip tekstą arba "wt" (write) rašytį į failą kaip tekstą (ir keletą kitų režimų, kuriuos čia praleisime). Toliau galima iškviesti failų objektų funkcijas. Dvi dažniausiai naudojamos funkcijos yra read (skaityti) ir write (rašyti). Funkcija write prideda eilutę prie failo pabaigos. Funkcija read nuskaito failo turinį ir grąžina jį kaip eilutę (kaip padaryta pavyzdyje).

O dabar čia yra nauja telefono numerių programos versija, kurią jau sukūrei anksčiau:

def spausdink_numerius(numeriai):
    print("Telefono numeriai:")
    for k, v in numeriai.items():
        print("Vardas:", k, "\tTelefono numeris:", v)
    print()

def pridėk_numerį(numeriai, vardas, numeris):
    numeriai[vardas] = numeris

def surask_numerį(numeriai, vardas):
    if vardas in numeriai:
        return "Telefono numeris yra " + numeriai[vardas]
    else:
        return vardas + " nebuvo rastas"

def pašalink_numerį(numeriai, vardas):
    if vardas in numeriai:
        del numeriai[vardas]
    else:
        print(vardas," nebuvo rastas")

def įkelti_numerius(numeriai, failo_pavadinimas):
    skaitymo_failas = open(failo_pavadinimas, "rt")
    while True:
        skaitoma_eilutė = skaitymo_failas.readline()
        if not skaitoma_eilutė:
            break
        skaitoma_eilutė = skaitoma_eilutė[:-1]
        vardas, numeris = skaitoma_eilutė.split(",")
        numeriai[vardas] = numeris
    skaitymo_failas.close()

def išsaugoti_numerius(numeriai, failo_pavadinimas):
    išvesties_failas = open(failo_pavadinimas, "wt")
    for k, v in numeriai.items():
        išvesties_failas.write(k + "," + v + "\n")
    išvesties_failas.close()

def spausdink_meniu():
    print('1. Spausdink telefonų numerius')
    print('2. Pridėk telefono numerį')
    print('3. Pašalink telefono numerį')
    print('4. Ieškok telefono numerio')
    print('5. Įkelk telefono numerius')
    print('6. Išsaugok telefono numerius')
    print('7. Išeik')
    print()

numeriai = {}
meniu_pasirinkimas = 0
spausdink_meniu()
while True:
    meniu_pasirinkimas = int(input("Įvesk skaičių (1-7): "))
    if meniu_pasirinkimas == 1:
        spausdink_numerius(numeriai)
    elif meniu_pasirinkimas == 2:
        print("Pridėk vardą ir telefono numerį")
        vardas = input("Vardas: ")
        numeris = input("Telefono numeris: ")
        pridėk_numerį(numeriai, vardas, numeris)
    elif meniu_pasirinkimas == 3:
        print("Pašalink vardą ir telefono numerį")
        vardas = input("Vardas: ")
        pašalink_numerį(numeriai, vardas)
    elif meniu_pasirinkimas == 4:
        print("Ieškok telefono numerio")
        vardas = input("Vardas: ")
        print(surask_numerį(numeriai, vardas))
    elif meniu_pasirinkimas == 5:
        failo_pavadinimas = input("Failo pavadinimas, kurį nori įkelti: ")
        įkelti_numerius(numeriai, failo_pavadinimas)
    elif meniu_pasirinkimas == 6:
        failo_pavadinimas = input("Failo pavadinimas išsaugojimui: ")
        išsaugoti_numerius(numeriai, failo_pavadinimas)
    elif meniu_pasirinkimas == 7:
        break
    else:
        spausdink_meniu()

print("Viso!")

Gali pastebėti, kad dabar kodas papildomai išsaugo ir perskaito failus. Štai dviejų programos vykdymų išvestis:

1. Spausdink telefonų numerius
2. Pridėk telefono numerį
3. Pašalink telefono numerį
4. Ieškok telefono numerio
5. Įkelk telefono numerius
6. Išsaugok telefono numerius
7. Išeik

Įvesk skaičių (1-7): 2
Pridėk vardą ir telefono numerį
Vardas: Liepa
Telefono numeris: 1234
Įvesk skaičių (1-7): 2
Pridėk vardą ir telefono numerį
Vardas: Benas
Telefono numeris: 4321
Įvesk skaičių (1-7): 1
Telefono numeriai:
Vardas: Liepa     Telefono numeris: 1234
Vardas: Benas     Telefono numeris: 4321

Įvesk skaičių (1-7): 6
Failo pavadinimas išsaugojimui: numeriai.txt
Įvesk skaičių (1-7): 7
Viso!
1. Spausdink telefonų numerius
2. Pridėk telefono numerį
3. Pašalink telefono numerį
4. Ieškok telefono numerio
5. Įkelk telefono numerius
6. Išsaugok telefono numerius
7. Išeik

Įvesk skaičių (1-7): 5
Failo pavadinimas, kurį nori įkelti: numeriai.txt
Įvesk skaičių (1-7): 1
Telefono numeriai:
Vardas: Liepa     Telefono numeris: 1234
Vardas: Benas     Telefono numeris: 4321

Įvesk skaičių (1-7): 7
Viso!

Naujos šios programos dalys yra:

def įkelti_numerius(numeriai, failo_pavadinimas):
    skaitymo_failas = open(failo_pavadinimas, "rt")
    while True:
        skaitoma_eilutė = skaitymo_failas.readline()
        if not skaitoma_eilutė:
            break
        skaitoma_eilutė = skaitoma_eilutė[:-1]
        vardas, numeris = skaitoma_eilutė.split(",")
        numeriai[vardas] = numeris
    skaitymo_failas.close()

def išsaugoti_numerius(numeriai, failo_pavadinimas):
    išvesties_failas = open(failo_pavadinimas, "wt")
    for k, v in numeriai.items():
        išvesties_failas.write(k + "," + v + "\n")
    išvesties_failas.close()

Pirmiausia pažiūrėk į programos išsaugojimo dalį. Visų pirma, sukuriamas failo objektas su komanda open(failo_pavadinimas, "wt"). Toliau sukuriama eilutė kiekvienam telefono numeriui su komanda išvesties_failas.write(k + "," + v + "\n"). Tai išrašo eilutę, kurioje yra vardas, kablelis, telefono numeris, o po jos rašoma nauja eilutė.

Failo skaitymo dalis yra šiek tiek sudėtingesnė. Ji prasideda failo objekto gavimu. Tada ji naudoja while True: ciklą, kad tęstųsi ciklas tol, kol bus aptikta komanda break. Komanda skaitoma_eilutė = skaitymo_failas.readline() perskaito pirmą eilutę ir priskiria kintamajam skaitome_eilutė. Pasiekus failo pabaigą, funkcija readline grąžins tuščią eilutę. Sąlyginis sakinys if tai patikrina ir panaudojant komandą break nutraukia while ciklą. Funkcija readline perskaito ir grąžina vieną eilutę kartu su jos pabaigos simboliu. Tai yra tam, kad būtų galima spręsti ar tai yra tik tuščia eilutė, ar jau failo pabaiga. Taigi turime atsikratyti to paskutinio eilutės pabaigos simbolio. Komanda skaitoma_eilutė = skaitoma_eilutė[:-1] tai padaro už mus, išmesdama paskutinį simbolį. Toliau eilutė vardas, numeris = skaitoma_eilutė.split(",") padalija eilutę ties kableliu į vardą ir telefono numerį ir visa tai įtraukiama į numeriai žodyną.

Pažangesnis .txt failų naudojimas

Galbūt tau kyla toks klausimas: „Aš žinau, kaip skaityti ir rašyti tekstinį failą, bet ką daryti, jei noriu atspausdinti failą spausdintuvu?"

Yra keletas skirtingų būdų, kaip tai padaryti. Iš tikrųjų, pats lengviausias būdas yra atidaryti kitą programą, tada leisti viskuo pasirūpinti Python'o kodui, kad tau nereikėtų pačiam failo atidarinėti ir spausdinti. Šis metodas apima kitos programos subproceso (arba antrinis procesas; biblioteka 'subprocess') iškvietimą.

Prisimeni failą, į kurį įrašėme išvestį aukščiau esančioje programoje? Panaudokime tą failą. Turėk omenyje, kad norint išvengti klaidų, ši programa naudoja sąvokas iš kito skyriaus. Nedvejodamas gali dar kartą peržiūrėti šį pavyzdį po kito skyriaus.

import subprocess
def pagrindinis():
    try:
        print("Ši maža programa iškviečia spausdinimo funkciją Notepad programoje")
        #Atspausdinkime failą, kurį sukūrėme aukščiau esančioje programoje
        subprocess.call(['notepad','/p','numeriai.txt'])
    except WindowsError:
        print("Pakviesto subproceso nėra arba jo negalima iškviesti.")

pagrindinis()

subprocess.call turi tris argumentus. Pirmasis argumentas šio pavyzdžio kontekste turėtų būti programos pavadinimas, iš kurios nori iškviesti spausdinimo subprocesą. Antrasis argumentas turėtų būti konkretus tos programos subprocesas. Kad būtų paprasčiau, tiesiog suprask, kad šioje programoje '/p' yra subprocesas, naudojamas norint pasiekti spausdintuvą per nurodytą programą. Paskutinis argumentas turėtų būti failo pavadinimas, kurį norite siųsti į spausdinimo subprocesą. Šiuo atveju tai yra tas pats failas, naudotas anksčiau šiame skyriuje.

Pratimai

Dabar pakeisk pažymių programą iš skyriaus Žodynai, kad ji naudotų failus mokinių pažymiams saugoti.

Sprendimas  
užduotys = ['nd sk 1', 'nd sk 2', 'viktorina   ', 'nd sk 3', 'testas']
mokiniai = { }

def įkelti_pažymius(pažymių_failas):
    įvesties_failas = open(pažymių_failas, "r")
    pažymiai = [ ]
    while True:
        mokinys_ir_pažymys = įvesties_failas.readline()
        mokinys_ir_pažymys = mokinys_ir_pažymys[:-1]
        if not mokinys_ir_pažymys:
            break
        else:
            mokinio_vardas, mokinio_pažymiai = mokinys_ir_pažymys.split(",")
            mokinio_pažymiai = mokinio_pažymiai.split(" ")
            mokiniai[mokinio_vardas] = mokinio_pažymiai
    įvesties_failas.close()
    print("Pažymiai įkelti.")

def išsaugoti_pažymius(pažymių_failas):
    išvesties_failas = open(pažymių_failas, "w")
    for k, v in mokiniai.items():
        išvesties_failas.write(k + ",")
        for x in v:
            išvesties_failas.write(str(x) + " ")
        išvesties_failas.write("\n")
    išvesties_failas.close()
    print("Pažymiai išsaugoti.")

def spausdink_meniu():
    print("1. Pridėk mokinį")
    print("2. Pašalink mokinį")
    print("3. Įkrauti pažymius")
    print("4. Įrašyk pažymį")
    print("5. Spausdink pažymius")
    print("6. Įšsaugoti pažymius")
    print("7. Spausdink meniu")
    print("9. Išeik")

def spausdink_visus_pažymius():
    if mokiniai:
        raktai = sorted(mokiniai.keys())
        print('\t', end=' ')
        for x in užduotys:
            print(x, '\t', end=' ')
        print()
        for x in raktai:
            print(x, '\t', end=' ')
            pažymiai = mokiniai[x]
            spausdink_pažymius(pažymiai)
    else:
        print("Neradau pažymių spausdinimui.")

def spausdink_pažymius(pažymiai):
    for x in pažymiai:
        print(x, '\t', end=' ')
    print()

spausdink_meniu()
meniu_pasirinkimas = 0
while meniu_pasirinkimas != 9:
    print()
    meniu_pasirinkimas = int(input("Meniu pasirinkimas: "))
    if meniu_pasirinkimas == 1:
        vardas = input("Pridėk mokinį: ")
        mokiniai[vardas] = [0] * len(užduotys)
    elif meniu_pasirinkimas == 2:
        vardas = input("Pašalink mokinį: ")
        if vardas in mokiniai:
            del mokiniai[vardas]
        else:
            print("Mokinys vardu:", vardas, " nerastas.")
    elif meniu_pasirinkimas == 3:
        pažymių_failas = input("Įkrauti pažymius iš kokio failo? ")
        įkelti_pažymius(pažymių_failas)
    elif meniu_pasirinkimas == 4:
        print("Įrašyk pažymį")
        vardas = input("Mokinys: ")
        if vardas in mokiniai:
            pažymiai = mokiniai[vardas]
            print("Įrašyk mokinio pažymį")
            print("Įrašyk 0 (nulį), kad išeitum")
            for i,x in enumerate(užduotys):
                print(i + 1, x, '\t', end=' ')
            print()
            spausdink_pažymius(pažymiai)
            kuris = 1234
            while kuris != -1:
                kuris = int(input("Pažymys, kurį nori pakeisti: "))
                kuris -= 1
                if 0 <= kuris < len(pažymiai):
                    pažymys = int(input("Pažymys: "))
                    pažymiai[kuris] = pažymys
                elif kuris != -1:
                    print("Klaidingas pažymys")
        else:
            print("Mokinys nerastas")
    elif meniu_pasirinkimas == 5:
        spausdink_visus_pažymius()
    elif meniu_pasirinkimas == 6:
        pažymių_failas = input("Į kokį failą išsaugoti pažymius? ")
        išsaugoti_pažymius(pažymių_failas)
    elif meniu_pasirinkimas != 9:
        spausdink_meniu()
 ← Daugiau apie tekstines eilutes Turinys Siekiant tobulumo →