Obsługa plików w Pythonie: tekst i obrazy

Obsługa plików w Pythonie jest prosta jak kilo sznurka w kieszeni — tak powinno brzmieć stare deweloperskie porzekadło!

Choć trzeba przyznać, że dedykowane biblioteki, jasne zasady odczytywania i mnóstwo smaczków (np. sczytywanie linijka po linijce, czytanie pliku za pomocą generatora) sprawiają, że wczytywanie, modyfikowanie i zapisywanie plików w Pythonie zazwyczaj jest dziecinnie proste.

Dzisiaj wracamy do podstaw i powtórzmy wszystko, co każdy dobry dev wiedzieć powinien. I kto wie – może nawet nauczysz się czegoś nowego…


Ścieżki w Pythonie

Zanim otworzysz pierwszy plik, warto upewnić się, że Python wie, gdzie go szukać. Praca ze ścieżkami może wydawać się błaha, ale w praktyce to częste źródło błędów.

Ścieżki relatywne i pathlib

Jedną z rzeczy, która może sprawiać trudności początkującym programistom (albo tym, którzy zmieniają środowisko pracy na Google Colab), jest ustalanie ścieżek. Serio! Nie ma nic bardziej denerwującego, niż odpalenie płatnego A100 tylko po to, żeby kod wysypał się na samym początku, bo w ścieżce jest ekstra slash. Albo go nie ma… Albo Python nagle stwierdzi, że jednak nie może znaleźć folderu, mimo że Ty widzisz, że on jak byk tam jest.

Dlatego zawsze używaj ścieżek relatywnych (bez / na początku!), a najlepiej korzystaj z biblioteki pathlib, która ogarnia systemy plików lepiej niż my sami.

from pathlib import Path


BAZA = Path(__file__).parent
plik = BAZA / "data" / "dane.txt"

with open(plik, "r", encoding="utf-8") as f:
    for linia in f:
        print(linia.strip())

To podejście jest nie tylko bezpieczne i wygodne, ale też przenośne między systemami bez względu na system operacyjny (https://docs.python.org/3/library/pathlib.html)..

Obsługa plików tekstowych

Pliki tekstowe to programistyczny chleb powszedni. Od logów po dane z sensorów – wszystko ląduje w .txt lub .csv. Na szczęście Python lubi prostotę, więc ich obsługa jest dziecinnie łatwa. Dosłownie kilka linijek kodu i już jesteś w domu.

I, żeby była jasność, nie chodzi mi tu o Wordy ani inne takie tak, ale o pliki .txt. Czy wiesz, że zapisany tekst potrafi zająć nawet 10x mniej miejsca, jeśli jest zapisany jako .txt, a nie .docx? Te-iks-teki są lekkie, czytelne i łatwe w obsłudze, a prawie wszystko zrobisz za pomocą jednej i tej samej funkcji open().

Odczyt pliku .txt

Czytanie plików tekstowych polega na otwarciu pliku w trybie odczytu i przetworzeniu jego zawartości – linia po linii lub jako całości:

plik = Path(__file__).parent / "data" / "notatki.txt"

with open(plik, "r", encoding="utf-8") as f:
    for linia in f:
        print(linia.strip())

with … as … to tzw. konstrukcja kontekstowa (context manager). Oznacza: „zrób coś (np. otwórz plik), a po zakończeniu – automatycznie posprzątaj”. Dzięki temu nie musisz pamiętać o zamykaniu pliku – Python zrobi to za Ciebie.

Literka “r” w parametrach funkcji open oznacza tryb otwierania pliku. Zazwyczaj użwamy tylko “r” do odczytu i “w” to zapisu, ale warto wiedzieć, że są inne opcje (np. “x”, jeśli chcesz mieć pewność, że przypadkiem nie nadpiszesz już istniejącego pliku.)..

TrybCo robiGdy plik NIE istniejeGdy plik ISTNIEJE
„r”read – tylko do odczytu❌ Błąd (FileNotFoundError)✅ Otwiera plik do czytania
„w”write – zapis (nadpisuje plik)✅ Tworzy nowy plik⚠️ Nadpisuje zawartość
„a”append – dopisywanie✅ Tworzy nowy plik✅ Dopisuje na końcu
„x”exclusive creation – zapis✅ Tworzy nowy plik❌ Błąd (jeśli plik istnieje)
„r+”odczyt i zapis❌ Błąd✅ Czyta i zapisuje (nie nadpisuje całego pliku!)
„w+”zapis i odczyt✅ Tworzy plik⚠️ Czyści zawartość i pozwala czytać/zapisywać
„a+”dopisywanie i odczyt✅ Tworzy plik✅ Czyta i dopisuje na końcu

Zapis do pliku .txt

Zapisywanie danych do pliku jest równie proste. Można w ten sposób przechowywać logi, wyniki analiz lub przetworzone dane. Jak widać, używamy tej samej funkcji co do odczytu, zmienia się tylko tryb – tu dajemy parametr “w”.

plik = Path(__file__).parent / "wyniki" / "raport.txt"

with open(plik, "w", encoding="utf-8") as f:
    f.write("Analiza zakończona sukcesem.\n")

!Dygresja!
Ta śmieszna składnia z dłuuuuugim podkreślnikiem (który nazywa się dunder) dookoła słowa kluczowego file („__file__”) oznacza ścieżkę do aktualnie uruchomionego pliku .py.

Obsługa plików CSV i JSON

W praktycznych projektach często pracujemy z danymi ustrukturyzowanymi. Python pozwala wygodnie operować na popularnych formatach, takich jak CSV i JSON.

Odczyt plików CSV i JSON

CSV to dane tabelaryczne, podobne do arkuszy kalkulacyjnych. JSON z kolei dobrze odwzorowuje złożone struktury, takie jak słowniki i listy.

import csv
import json

plik_csv = Path(__file__).parent / "data" / "dane.csv"
plik_json = Path(__file__).parent / "data" / "konfiguracja.json"

# CSV
with open(plik_csv, "r") as f:
    reader = csv.reader(f)
    for wiersz in reader:
        print(wiersz)

# JSON
with open(plik_json, "r") as f:
    dane = json.load(f)
    print(dane)

Zarówno csv.reader, jak i json.load pozwalają na szybki dostęp do danych i ich dalsze przetwarzanie.

Praca z dużymi plikami

Kiedy dane zaczynają ważyć setki megabajtów lub więcej, warto sięgnąć po techniki, które nie przeciążają pamięci operacyjnej. Python oferuje tu bardzo eleganckie rozwiązanie – generatory.

Czytanie pliku linia po linii za pomocą generatora

Generator pozwala na przetwarzanie dużych plików bez ich wczytywania w całości do pamięci. To podejście idealnie sprawdza się przy logach, transakcjach, danych czujnikowych i wielu innych zastosowaniach.

def czytaj_duzy_plik(plik):
    with open(plik, 'r', encoding='utf-8') as f:
        for linia in f:
            yield linia.strip()

plik = Path(__file__).parent / "data" / "duzy.txt"

for linia in czytaj_duzy_plik(plik):
    przetworz(linia)

W ten sposób możemy przetwarzać dane sekwencyjnie, nie martwiąc się o zużycie pamięci.

Obsługa plików graficznych

Pliki graficzne to dane binarne, które wymagają odpowiednich bibliotek i metod. W Pythonie najczęściej korzysta się z biblioteki Pillow, która oferuje funkcje do wczytywania, przekształcania i zapisywania obrazów.

Wczytywanie i zapisywanie obrazów

Podstawowa operacja to otwarcie obrazu, zmiana jego formatu lub rozmiaru i zapisanie efektu końcowego.

from PIL import Image

sciezka = Path(__file__).parent / "obrazy" / "pies.jpg"

img = Image.open(sciezka)
img = img.convert("RGB")
img = img.resize((224, 224))
img.save(Path(__file__).parent / "obrazy" / "pies_224.jpg")

To wystarcza do większości zadań związanych z przygotowaniem obrazów do dalszej analizy.

Tryby wczytywania obrazów

Domyślnie obraz zachowuje swój oryginalny tryb, czyli taki, w jakim został zapisany na dysku. 

Plik źródłowyCo zostaje po Image.open(…)Tryb obrazu (img.mode)
.jpgKolor bez przezroczystości„RGB”
.png (z alfa)Kolor z przezroczystością„RGBA”
.png (bez alfa)Kolor bez przezroczystości„RGB”
.gifIndeksowana paleta kolorów„P”
.bmpZależnie od wersji pliku„RGB” lub „P”
.tifMoże być „L”, „RGB”, „CMYK”zależnie od wersji

Jeśli chcesz zmienić tryb obrazu, musisz go następnie skonwertować. Jest to szczególnie ważne, jeśli szykujesz dataset z obrazami z różnych źródeł. Mogą być zapisane w różnych trybach, przez co model nie będzie w stanie na nich trenować. W takiej sytuacji dobrym nawykiem jest standaryzacja obrazów przy wczytywaniu. Wtedy masz pewność, że wszystkie obrazy są w tym samym formacie, z tą samą liczbą kanałów i gotowe do zamiany na tensory lub tablice NumPy.

Najważniejsze tryby w Image.convert()

TrybNazwaOpis
„1”1-bitowy (czarno-biały)Obraz binarny – tylko czarny i biały (bez odcieni szarości). Idealny np. do druku.
„L”Grayscale (8-bit)Skala szarości – od 0 (czarne) do 255 (białe). Jeden kanał.
„RGB”Kolor (3 kanały)Pełny kolor: czerwony, zielony, niebieski. Najczęściej używany tryb.
„RGBA”Kolor + przezroczystośćRGB z dodatkowym kanałem alfa (przezroczystość).
„CMYK”Drukarski kolorUżywany w druku (cyan, magenta, yellow, black).
„P”Paleta kolorówObraz indeksowany – 256 kolorów z palety. Lżejszy, ale mniej precyzyjny.
„LA”Luminancja + alfaSkala szarości z kanałem przezroczystości.
„I”32-bit integerKażdy piksel to liczba całkowita (do celów naukowych, np. analiza obrazu).
„F”32-bit floatKażdy piksel to liczba zmiennoprzecinkowa – np. do precyzyjnych analiz.

Na przykład, Jeśli kolor nie ma znaczenia (OCR, niektóre zdjęcia medyczne) – można ograniczyć dane do jednego kanału i zaoszczędzić trochę miejsca.

szary = Image.open(sciezka).convert("L")
szary.save(Path(__file__).parent / "obrazy" / "pies_szary.jpg")

Przetwarzanie wielu obrazów z folderu

Przy pracy z dużymi zbiorami danych graficznych (np. podczas trenowania modelu) nie warto ładować wszystkich obrazów do pamięci jednocześnie. Z pomocą przychodzi generator:

def obrazy_z_folderu(folder):
    for plik in folder.iterdir():
        if plik.suffix in [".jpg", ".png", ".tif"]:
            yield Image.open(plik)

folder = Path(__file__).parent / "obrazy"

for img in obrazy_z_folderu(folder):
    przetworz(img)

Dla niewytrenowanego oka wygląda to jak funkcja, która po prostu otwiera pliki w folderze. Ale dzięki słowu kluczowemu yield wiemy, że to generator i będzie pobierał kolejno obrazy, praktycznie nie zajmując pamięci procesora. Taki sposób przetwarzania obrazów jest wydajny, skalowalny i bezpieczny nawet przy bardzo dużych zbiorach danych.

Podsumowanie

Obsługa plików w Pythonie opiera się na kilku prostych zasadach:

  • używaj pathlib do zarządzania ścieżkami,
  • zawsze pracuj z plikami w bloku with open(…),
  • stosuj dedykowane biblioteki: csv, json, Pillow,
  • używaj najbardziej optymalnego trybu otwierania plików tekstowych (nie tylko “r” i “w”),
  • w razie korzystanie ze zróżnicowanego datasetu, domyślnie konwertuj otwierane obrazy do wybranego trybu,
  • korzystaj z generatorów przy dużych zbiorach danych.

Niby proste, a zdziwisz się, jak wielu devów zapomina, że nie zawsze trzeba nadpisywać plik od zera albo że model nie wywali się, jeśli z automatu skonwertujemy obrazy do jednolitego trybu.

W najbliższym czasie przygotuję ściągę do wydruku z najważniejszymi informacjami dot. obsługi plików. Wydrukuj ją i przyczep nad biurkiem. 

Niniejszy tutorial jest częścią kursu Podstawy Pythona, który szykuje nas do ścieżki kariery na Programistę AI. Zachęcam Cię do zapoznania się z obiema stronkami i wspólną naukę. Kto wie – może za jakiś czas będziesz robić modele do rozpoznawania obrazów i z łezką w oku wspomnisz portal, dzięki któremu Twój model nie wysypał się już na etapie otwierania plików… No dobra, chyba trochę mnie poniosło! 😉

ai-generated image of a butterfly breaking the fourth wall and sitting on a flower image within a CRT scren

Co dalej?

Zapisz się do naszego newslettera, żeby nigdy nie przegapić żadnego wartościowego artykułu.

Zajrzyj do sekcji Kariera w AI, gdzie znajdziesz konkretne materiały o zmianach na rynku pracy – w Polsce i na świecie – oraz ścieżkach kariery związanych ze sztuczną inteligencją (nie tylko jako programista!).

→ A jeśli chcesz pisać modele i pracować jako Architekt AI, ale nie wiesz, od czego zacząć (lub utknąłeś gdzieś na ścieżce), odwiedź dział Nauka AI – czeka tam wiedza, ciekawostki i realne wsparcie.


! Uwaga

Niniejszy ebook ma charakter informacyjny i edukacyjny. Nie stanowi porady prawnej ani oferty pracy w rozumieniu przepisów krajowych lub unijnych.
Przy tworzeniu niniejszego artykułu korzystano ze wsparcia narzędzi opartych na sztucznej inteligencji – m.in. w zakresie porządkowania treści, analizy źródeł, przyspieszenia redakcji i wyszukiwania źródeł Jednak wszelkie decyzje dotycząca treści, interpretacji i ostatecznej formy zostały podjęte przez człowieka.

Podziel się swoją opinią

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *