Vadovėlis/Failų tvarkymas
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ą.
Darbo su failais rėžimai
Be "rt"
ir "wt"
yra ir kitų darbo su failais rėžimų. Lentelėje rasi visų rėžimų sąrašą:
Rėžimas | Paaiškinimas |
---|---|
"rt" | Tekstinio failo nuskatymas |
"wt" | Teksto rašymas į failą |
"xt" | Naujo teskinio failo kūrimas. Jei toks failas jau egzistuoja bus gaunama klaida |
"at" | Tekstinio failo papildymas. Failo turinys bus pildomas nuo edamo failo pabaigos |
"r" | Sinonimas "rt" rėžimui. Tekstinio failo nuskatymas |
"w" | Sinonimas "w" rėžimui. Teksto rašymas į failą |
"x" | Sinonimas "x" rėžimui. Naujo teskinio failo kūrimas. Jei toks failas jau egzistuoja bus gaunama klaida |
"a" | Sinonimas "a" rėžimui. Tekstinio failo papildymas. Failo turinys bus pildomas nuo edamo failo pabaigos |
"rb" | Dvejetainio duomenų failo nuskatymas |
"wb" | Dvejetainės informacijos rašymas į failą |
"xb" | Naujo dvejetainio failo kūrimas. Jei toks failas jau egzistuoja bus gaunama klaida |
"ab" | Dvejetainio failo papildymas. Failo turinys bus pildomas nuo edamo failo pabaigos |
"r+" | Tekstinio failo skaitymas ir rašymas. Esamas failo turinys nėra išvalomas. |
"w+" | Tekstinio failo skaitymas ir rašymas. Esamas failo turinys yra išvalomas rašant į failą. |
"r+b" | Dvejetainio failo skaitymas ir rašymas. Esamas failo turinys nėra išvalomas. |
"w+b" | Dvejetainio failo skaitymas ir rašymas. Esamas failo turinys yra išvalomas rašant į failą. |
Dvvejetainiai rėžimai šiame vadovėlyje plačiau nagrinėjami nėra
Pagrindinės darbo su tekstiniais failais operacijos
Operacija | Paaiškinimas |
---|---|
failas.read() | Nuskaitomas visas failo turinys |
failas.read(kiek) | Nuskaitomas nuordytas simbolių kiekis iš failo. Pvz naudojant failas.read(3) bus nuskaitomi 3 sekantys simboliai |
failas.readline() | Nuskaitoma sekanti failo eilutė |
failas.readlines() | Nuskaitomos visos failo eilutės. Gražinamas sąrašas sudarytas iš teksto eilučių |
failas.close() | Failo uždarymas. Uždarius failą veiksmai su juo negalimi. Atidarant failą naudojant with funkciją, jis bus uždarytas automatiškai, tad close() naudoti nebereikia |
failas.write(rašomas_tesktas) | Įrašo nurodytą tekstą į failą. |
failas.writelines(rašomo_teksto_eilučių_sąrašas) | Sąrašas sudarytas iš teskto eilučių yra įrašomas į failą. Kiekvienas sąrašo elementas bus įrašomas naujoje eilutėje |
Paketinis ir interaktyvus failų apdorojimas
Failai gali būti apdorojami įvairiais būdais. Vieni iš dažniausiai naudojamų ir naudingiausių būdų - tai paketinis duomenų apdorojimas ir interaktyvus duomenų apdorojimas.
Skaitymas iš failo yra vadinamas paketiniu duomenų apdorojimu, nes visi duomenys iš failo yra nuskaitomi ir apdorojami kaip vienas paketas. Tai reiškia, kad visi duomenys yra nuskaitomi iš failo į kompiuterio atmintį vienu metu ir toliau apdorojami kompiuterio procesorių, o ne tiesiogiai iš failo.
Pavyzdžiui, jei turi didelio dydžio tekstinį failą ir nori jį apdoroti programoje, failas bus nuskaitomas į atmintį ir tada apdorotas kaip vienas paketas, o ne kaip atskiri duomenų elementai.
Interaktyvus duomenų apdorojimas – tai būdas dirbti su duomenimis, kai vartotojas gali manipuliuoti įvairiais nustatymais, o ne laikytis iš anksto užprogramuotų algoritmų. Tai leidžia geriau valdyti rezultatus ir geriau suprasti duomenis.
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
1. Parašyk programą, kuri suskaičiuotų, kiek faile yra eilučių.
Sprendimas | |
---|---|
failas = input("Kokio failo eilutes skaičiuoti? ") įvesties_failas = open(failas, "r") eilutės = įvesties_failas.readlines() įvesties_failas.close() print("Failas", failas, "turi", len(eilutės), " eilutes") |
2. Parašyk programą, kuri nukopijuotų vieno failo lygines eilutes į kitą failą.
Sprendimas | |
---|---|
įvesties_failo_pavadinimas = input("Kokio failo eilutes kopijuoti? ") įvesties_failas = open(įvesties_failo_pavadinimas, "r") išvesties_failo_pavadinimas = input("Į kokį failą išsaugoti lygines eilutes? ") išvesties_failas = open(išvesties_failo_pavadinimas, "w") eilutės_numeris = 0 while True: eilutė = įvesties_failas.readline() eilutės_numeris = eilutės_numeris + 1 if not eilutė: break else: if (eilutės_numeris % 2) == 0: išvesties_failas.write(eilutė) įvesties_failas.close() išvesties_failas.close() |
3. 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() |