Operacje na plikach są wykorzystywane w wielu zagadnieniach programistycznych, inżynierskich, naukowych i analizie danych. Jednym z takich zagadnień może być masowa obróbka plików graficznych (np. zmiana rozmiaru, kolorów), filtrowanie plików o wybranych rozszerzeniach i wiele innych. Język Python dysponuje sporym zbiorem funkcji wbudowanych do operacji na plikach. Funkcjonalność języka w tym obszarze możemy poszerzyć wykorzystując bardziej specjalistyczne biblioteki. Poniżej omówię podstawy obsługi plików, czyli takie zadania jak odczyt, zapis czy kopiowanie.
Otwieranie pliku
Przed wykonaniem jakichkolwiek działań na pliku, musimy go najpierw otworzyć. Zrobimy to przy użyciu funkcji open()
. Posłużymy się przykładowym plikiem tekstowym plik1.txt o treści:
To jest przykladowy plik tekstowy.
Do zobaczenia!
Plik otwieramy przy użyciu instrukcji:
plik1 = open("plik1.txt")
Pliki możemy otwierać w różnych trybach. Domyślnie plik jest otwierany w trybie tylko do odczytu. Do wskazania, który tryb chcemy wykorzystać, używamy dodatkowego argumentu, jak w poniższych przykładach:
- Tryb odczytu (
'r'
): Pozwala na odczytanie zawartości istniejącego pliku. Jeśli plik nie istnieje, wystąpi błąd.
file = open('plik1.txt', 'r')
- Tryb zapisu (
'w'
): Tworzy nowy plik do zapisu danych. Jeśli plik już istnieje, nadpisuje go nową zawartością.
file = open('plik1.txt', 'w')
- Tryb dopisywania (
'a'
): Otwiera plik do dopisywania danych na końcu istniejącej zawartości. Jeśli plik nie istnieje, tworzy nowy.
file = open('plik1.txt', 'a')
Wczytywanie danych z pliku tekstowego do Pythona
Wczytywanie całego pliku
Po otwarciu pliku możemy wczytać jego treść do jednej zmiennej za pomocą funkcji read()
:
# otwórz plik
plik = open("plik1.txt")
# wczytaj plik
read_content = plik.read()
print(read_content)
plik.close()
Wynik:
To jest przykladowy plik tekstowy.
Do zobaczenia!
Po otwarciu pliku za pomocą funkcji open()
zaleca się jego zamknięcie za pomocą funkcji close()
, aby zwolnić zasoby systemowe i zapobiec problemom związanych z dostępem do otwartych plików. W Pythonie istnieje alternatywna składnia z użyciem instrukcji with
, która automatycznie zarządza zamknięciem pliku po opuszczeniu bloku, o czym przekonamy się za chwilę.
Wczytywanie danych linia po linii
Prostym sposobem wczytywania danych z pliku tekstowego jest odczytanie go linia po linii i przetworzenie każdej linii oddzielnie. Możemy to zrobić za pomocą wbudowanej funkcji readline()
do odczytania kolejnych linii. Przykładowy kod wygląda następująco:
# Otwieramy plik tekstowy do odczytu
with open('plik1.txt', 'r') as file:
# Odczytujemy kolejne linie z pliku
for line in file:
print(line.strip()) # usuwamy białe znaki z końca i początku linii
Wczytywanie danych jako listy
Jeśli chcemy wczytać całą zawartość pliku tekstowego do pamięci jako listę, możemy użyć funkcji readlines()
. Ta metoda odczytuje cały plik i zwraca listę, gdzie każdy element listy odpowiada jednej linii z pliku.
# Otwieramy plik tekstowy do odczytu
with open('plik1.txt', 'r') as file:
# Wczytujemy całą zawartość pliku do listy
lines = file.readlines()
# Wyświetlamy wczytane linie
for line in lines:
print(line.strip()) # usuwamy białe znaki z końca i początku linii
Zapis do pliku
Zapis przy użyciu funkcji write
Aby zapisać treść do pliku musimy otworzyć z parametrem w
. Do zapisu wykorzystujemy funkcję write()
.
# otwórz plik2.txt w trybie do zapisu
plik2 = open('plik2.txt', 'w')
# zapisz treść do plik2.txt
plik2.write('Zapisana tresc do pliku.\n')
plik2.write('Koniec pliku.\n')
plik2.close()
Zwróćmy uwagę, że każda linia zapisywana do pliku zakończona jest znakiem końca linii, czyli \n
. Gdybśmy pominęli ten znak, to funkcja write()
dopisałaby ciąg znaków w tej samej linii, a plik po modyfikacji wyglądałby tak:
Zapisana tresc do pliku.Koniec pliku.
Kolejną kwestią jest konieczność zamknięcia pliku przy użyciu funkcji close()
, co jest konieczne, aby program wprowadził w nim zmiany. Jeżeli tego nie zrobimy, to możemy mieć również problemy z dostępem do pliku przez inne programy.
Zapis do pliku przy użyciu with open
Możemy również skorzystać z wcześniej wspomnianej instrukcji with.
# Dane do dopisania
nowe_dane = "Nowe dane, ktore zostana dopisane do pliku."
# Otwarcie pliku w trybie dopisywania ('a' - append)
with open('plik_do_zapisu.txt', 'w') as file:
# Dopisanie nowych danych do pliku
file.write("\n") # Dodanie nowej linii przed nowymi danymi
file.write(nowe_dane)
print("Nowe dane zostaly dopisane do pliku.")
Korzystanie z trybu dopisywania
Tryb ten służy do dołączania treści do istniejącego już pliku. W tym ćwiczeniu wykorzystamy wcześniej stworzony plik plik1.txt, do którego dodamy nową linijkę tekstu.
# Przykład zastosowania trybu append()
plik = open('plik1.txt', 'a')
plik.write("\n") # Dodanie nowej linii przed nowymi danymi
plik.write("To jest nowa linia")
plik.close()
Po uruchomieniu programu, plik1.txt będzie wyglądał następująco:
To jest przykladowy plik tekstowy.
Do zobaczenia!
To jest nowa linia
Zwróćmy uwagę, że użycie trybu zapisu 'w'
spowodowałoby nadpisanie całej zawartości pliku.
Zapis polskich znaków do pliku tekstowego
We wcześniejszych przykładach nie stosowaliśmy polskich znaków. Użycie ich wywołałoby błąd UnicodeEncodeError
. Związane jest to z próbą zapisu znaków, które nie są obsługiwane w standardzie kodowania cp1252
, który jest domyślnym kodowaniem w niektórych systemach Windows. Rozwiązaniem tego problemu jest ustawienie kodowania na utf-8
, które pozwoli na zapisywanie znaków Unicode.
plik2 = open('plik2.txt', 'w', encoding='utf-8')
# zapisz treść do plik2.txt
plik2.write('Zapisana treść do pliku.\n')
plik2.write('Koniec pliku.\n')
plik2.close()
Wbudowane funkcje Python do odczytu i zapisu
Oprócz wyżej wymienionych funkcji Python dostarcza jeszcze kilka wbudowanych funkcji służących do odczytu i zapisu w plikach. Poniżej przedstawiłem kilka przykładowych:
readline()
: odczytuje linię z pliku i zwraca jako ciąg znaków.readlines()
: zwraca listę, w której każdy element jest pojedynczą linią pliku.writelines()
: zapisuje listę ciągów znaków do pliku.append()
: dołącza ciąg znaków do pliku zamiast nadpisywać plik.seek()
: przesuwa wskaźnik pozycji w pliku na określoną pozycję.
Kopiowanie pliku w Pythonie przy użyciu modułu shutil
Do kopiowania plików możemy użyć modułu shutil
, a konkretnie funkcję copyfiles()
:
import shutil
# Ścieżka pliku źródłowego i docelowego
plik_zrodlowy = 'e:\Folder_1\plik.txt'
plik_docelowy = 'e:\Folder_2\plik.txt'
# Skopiowanie pliku z plik_zrodlowy.txt do plik_docelowy.txt
shutil.copyfile(plik_zrodlowy, plik_docelowy)
print("Plik został skopiowany.")
Funkcja copyfile()
kopiuje zawartość pliku źródłowego do pliku docelowego. Jeśli plik docelowy już istnieje, zostanie on nadpisany.
Usuwanie pliku w Pythonie przy użyciu modułu os
Do usuwania plików w Pythonie służy funkcja remove()
z modułu os
.
import os
# Ścieżka do pliku, który chcemy usunąć
sciezka_do_pliku = 'e:\Folder_2\plik.txt'
# Sprawdzenie, czy plik istnieje
if os.path.exists(sciezka_do_pliku):
# Usunięcie pliku
os.remove(sciezka_do_pliku)
print(f"Plik {sciezka_do_pliku} został usunięty.")
else:
print(f"Plik {sciezka_do_pliku} nie istnieje.")
W powyższym przykładzie widzimy, że zanim usuniemy plik (linia 9), to sprawdzamy czy ten plik istnieje przy użyciu funkcji os.path.exists()
. Wynika to z faktu, że gdybyśmy chcieli usunąć nieistniejący plik, to program zwróciłby błąd:
FileNotFoundError
Alternatywnym podejściem jest obsługa wyjątków, która opisana zostanie bardziej obszernie w innym artykule. W tym rozwiązaniu fragment kodu, który może wywołać FileNotFoundError umieszczamy w bloku try
. W przypadku wystąpienia tego błędu zostanie on przechwycony przez instrukcję except
. Kod programu wygląda następująco:
import os
sciezka_do_pliku = 'plik_do_usuniecia.txt'
try:
os.remove(sciezka_do_pliku)
print(f"Plik {sciezka_do_pliku} został usunięty.")
except FileNotFoundError as e:
print(f"Błąd podczas usuwania pliku {sciezka_do_pliku}: {e}")
Pliki csv
CSV (ang. comma-separated values) to popularny format pliku tekstowego, w którym dane odzwierciedlają zapis tabelaryczny. Każda linia w pliku csv reprezentuje wiersz tabeli, a wartości oddzielane przecinkiem, bądź innym zdefiniowanym znakiem, odpowiadają poszczególnym komórkom tabeli. Weźmy przykładowy plik kontakty.csv, o następującej treści:
Imię,Nazwisko,Email,Telefon
Jan,Kowalski,[email protected],123456789
Anna,Nowak,[email protected],987654321
Plik ten w formie tabelarycznej (np. w Excelu) wyglądałby następująco:
Imię | Nazwisko | Telefon | |
---|---|---|---|
Jan | Kowalski | [email protected] | 123456789 |
Anna | Nowak | [email protected] | 987654321 |
Pliki csv są bardzo przydatne, ze względu na prostą strukturę i łatwość odczytu i zapisu. Z tego względu również w Pythonie bardzo często korzysta się z tego formatu. Przyjrzyjmy się jak najprościej wczytać i zapisać dane do pliku csv.
import csv
# Otwórz plik CSV w trybie odczytu
with open('kontakty.csv', 'r') as csvfile:
# Utwórz obiekt reader
reader = csv.reader(csvfile, delimiter=',')
# Pomiń nagłówek
next(reader, None)
# Iteruj po wierszach pliku
for row in reader:
print(row)
Wynik:
['Jan', 'Kowalski', '[email protected]', '123456789']
['Anna', 'Nowak', '[email protected]', '987654321']
Poniż przykład pokazuje jak dopisać dane do pliku csv.
# Otwórz plik CSV w trybie dopisywania
with open('kontakty.csv', 'a', newline='', encoding='utf-8') as csvfile:
# Utwórz obiekt writer
writer = csv.writer(csvfile, delimiter=',')
# Zapisz wiersze do pliku
writer.writerow(['Rafał', 'Marcinkiewicz', '[email protected]', '34545634'])
Po wykonaniu programu plik kontakty.csv będzie wyglądał następująco:
['Jan', 'Kowalski', '[email protected]', '123456789']
['Anna', 'Nowak', '[email protected]', '987654321']
['Rafał', 'Marcinkiewicz', '[email protected]', '34545634']
Peklowanie
Peklowanie (ang. pickling) służy do tzw. serializacji, czyli procesu polegającego na zapisie na dysku dowolnego obiektu Pythona, np. listy, słownika, krotki, itp. Taki plik zapisany w postaci strumienia bajtów zawiera wszystkie niezbędne informacje o obiekcie, dzięki czemu można go zrekonstruować, czyli odpeklować i przywrócić do pierwotnej postaci w dowolnym skrypcie Pythona.
W poniższym przykładzie zapiklujemy przykładowy słownik.
# Peklowanie
import pickle
# Tworzenie przykładowego słownika
dane = {
'imię': 'Jan',
'wiek': 30,
'miasto': 'Warszawa'
}
# Zapisywanie słownika do pliku za pomocą pickle
with open('dane.pickle', 'wb') as plik:
pickle.dump(dane, plik)
W linii 2 importujemy moduł pickle
zawierający funkcje niezbędne w procesie peklowania. W linii 5 tworzymy przykładowy słownik. W linii 12 otwieramy plik przy użyciu wcześniej omówionej konstrukcji with open
. Zwróćmy uwagę, że plik otwieramy w trybie wb
, czyli ‘write binary’, z uwagi na to, że pickle to plik binarny. W linii 13 wykonujemy zapis do pliku przy użyciu funkcji plickle.dump
.
Proces odwrotny, czyli odpeklowanie, wykonujemy przy użyciu funkcji pickle.load
. W przykładzie poniżej wczytujemy dane do zmiennej, której automatycznie przypisana zostaje struktura słownika.
# Odczytywanie słownika z pliku za pomocą pickle
with open('dane.pickle', 'rb') as plik:
wczytane_dane = pickle.load(plik)
print("Wczytane dane:", wczytane_dane)
Wynik:
Wczytane dane: {'imię': 'Jan', 'wiek': 30, 'miasto': 'Warszawa'}