Rozdział 15 · Python i akta
Binarki i podziały linii
Nie wszystko, co znajduje się w pliku, to tekst. A nawet tekst zajmuje na dysku więcej, niż się wydaje.
Tryb binarny
Dodaj b w tryb, aby pracować z plikiem jako czystymi
bajtami, bez jakiegokolwiek kodowania tekstowego:
binarny_fajl.py
data = bytes([0, 1, 2, 3, 255])
with open("signal.bin", "wb") as f:
f.write(data)
with open("signal.bin", "rb") as f:
print(f.read()) # b'\\x00\\x01\\x02\\x03\\xff'
| Mode | Co dostajemy w Python | Przykład |
|---|---|---|
"rt" / "r" | str (tekst) | "Python" |
"rb" | bytes (dane binarne) | b'Python' |
Nie dekoduj dowolnych danych binarnych jako tekst
PNG, JPEG lub PDF nie będą czytelne z
open(..., encoding="utf-8") — to nie są dane tekstowe i próba odczytu ich jako tekstu spowoduje błąd lub śmieci. Do takich formatów używaj trybu binarnego ("rb") lub specjalistyczna biblioteka dla tego formatu.Debug Lab 9: Dane binarne odczytywane jako tekst
bin_kak_text.py
data = bytes([0, 1, 2, 3, 255])
with open("signal.bin", "wb") as f:
f.write(data)
with open("signal.bin", "r", encoding="utf-8") as f:
print(f.read())
Traceback (most recent call last):
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 4: invalid start byte
bajtów 0xff nie tworzy prawidłowego znaku w UTF-8 — te dane nigdy nie były tekstem. Plik musi być otwarty w trybie binarnym ("rb"), a nie w formie tekstowej.
Poprawiony kod
bin_pravilno.py
with open("signal.bin", "rb") as f:
print(f.read()) # b'\\x00\\x01\\x02\\x03\\xff'
Zawijanie wierszy i tryb tekstowy
\n wewnątrz Python jest uniwersalny kanał przewodowy
Na różnych systemach operacyjnych historycznie stosowano różne sekwencje do przechodzenia do nowej linii na dysku (np.,
\r\n w plikach utworzonych w Windows). trybie tekstowym Python odczytuje takie pliki w trybie uniwersalnych podziałów linii i przekazuje je Ci we wszystkich przypadkach \n — nie musicie przetwarzać obu wariantów ręcznie w zwykłym kodzie tekstowym.Postacie kontra bajty – przykład z rzeczywistego świata
simvoly_vs_bajty.py
text = „Python🐍”
print(len(text)) # 6 — liczba znaków
print(len(text.encode("utf-8"))) #14 to liczba bajtów w UTF-8
Długość tekstu ≠ rozmiar pliku w bajtach
cyrylicy i emoji zajmują kilka bajtów na znak w UTF-8.
len(text) liczy znaki, a nie bajty — rozmiar pliku na dysku może być znacznie większy niż liczba znaków w łańcuch znaków.Praktyka: pliki binarne i przenoszenie linii
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji