{"id":1429,"date":"2026-04-06T13:46:50","date_gmt":"2026-04-06T11:46:50","guid":{"rendered":"https:\/\/trzykody.pl\/?p=1429"},"modified":"2026-04-21T13:54:12","modified_gmt":"2026-04-21T11:54:12","slug":"bytearray-tworzy-mutowalna-sekwencje-bajtow","status":"publish","type":"post","link":"https:\/\/trzykody.pl\/index.php\/2026\/04\/06\/bytearray-tworzy-mutowalna-sekwencje-bajtow\/","title":{"rendered":"Bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w"},"content":{"rendered":"\n<p>Praca na danych binarnych pojawia si\u0119 szybciej, ni\u017c zwykle zak\u0142ada pocz\u0105tkuj\u0105cy programista. Odczyt plik\u00f3w, komunikacja po sieci, analiza ramek protoko\u0142\u00f3w, operacje na obrazach, archiwach czy danych z urz\u0105dze\u0144 \u2013 wsz\u0119dzie tam operujemy nie na znakach, ale na bajtach. R\u00f3\u017cnica mi\u0119dzy obiektem niemodyfikowalnym a takim, kt\u00f3ry mo\u017cna zmienia\u0107 w miejscu, ma wtedy realne znaczenie dla wydajno\u015bci i czytelno\u015bci kodu. W Pythonie w\u0142a\u015bnie do tego s\u0142u\u017cy <strong>bytearray<\/strong> \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Spis Tre\u015bci<\/h2><nav><ol><li><a href=\"#dlaczego-praca-na-bajtach-jest-inna-niz-operacje-na-zwyklych-lancuchach-znakow\">Dlaczego praca na bajtach jest inna ni\u017c operacje na zwyk\u0142ych \u0142a\u0144cuchach znak\u00f3w<\/a><\/li><li><a href=\"#bytearray-tworzy-mutowalna-sekwencje-bajtow-i-dlatego-rozni-sie-od-typu-bytes\">bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w i dlatego r\u00f3\u017cni si\u0119 od typu bytes<\/a><\/li><li><a href=\"#operacje-podstawowe-i-mechanika-dzialania-indeksowania-oraz-modyfikacji-danych\">Operacje podstawowe i mechanika dzia\u0142ania indeksowania oraz modyfikacji danych<\/a><\/li><li><a href=\"#przyklady-kodu-w-c-c-i-python-pokazujace-podobna-idee-pracy-na-buforze-bajtowym\">Przyk\u0142ady kodu w C, C++ i Python pokazuj\u0105ce podobn\u0105 ide\u0119 pracy na buforze bajtowym<\/a><\/li><li><a href=\"#bytearray-tworzy-mutowalna-sekwencje-bajtow-podczas-pracy-z-plikami-siecia-i-buforami-danych\">bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w podczas pracy z plikami, sieci\u0105 i buforami danych<\/a><ol><li><a href=\"#odczyt-i-modyfikacja-plikow-binarnych\">Odczyt i modyfikacja plik\u00f3w binarnych<\/a><\/li><li><a href=\"#bufory-sieciowe\">Bufory sieciowe<\/a><\/li><li><a href=\"#komunikacja-z-urzadzeniami\">Komunikacja z urz\u0105dzeniami<\/a><\/li><\/ol><\/li><li><a href=\"#zaleznosc-miedzy-bytes-bytearray-i-pamiecia-programu-podczas-wykonywania-operacji\">Zale\u017cno\u015b\u0107 mi\u0119dzy bytes, bytearray i pami\u0119ci\u0105 programu podczas wykonywania operacji<\/a><\/li><li><a href=\"#wzory-i-reprezentacje-liczbowe-potrzebne-do-zrozumienia-zapisu-bajtow\">Wzory i reprezentacje liczbowe potrzebne do zrozumienia zapisu bajt\u00f3w<\/a><\/li><li><a href=\"#bytearray-tworzy-mutowalna-sekwencje-bajtow-a-poprawne-uzycie-zmniejsza-liczbe-bledow-pamieci\">bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w a poprawne u\u017cycie zmniejsza liczb\u0119 b\u0142\u0119d\u00f3w pami\u0119ci<\/a><\/li><li><a href=\"#faq\">FAQ<\/a><ol><li><a href=\"#czy-bytearray-jest-szybszy-od-bytes\">Czy bytearray jest szybszy od bytes<\/a><\/li><li><a href=\"#czy-mozna-zamienic-bytearray-na-bytes\">Czy mo\u017cna zamieni\u0107 bytearray na bytes<\/a><\/li><li><a href=\"#czy-bytearray-mozna-sortowac\">Czy bytearray mo\u017cna sortowa\u0107<\/a><\/li><li><a href=\"#czy-bytearray-nadaje-sie-do-duzych-plikow\">Czy bytearray nadaje si\u0119 do du\u017cych plik\u00f3w<\/a><\/li><li><a href=\"#czy-pojedynczy-element-jest-typu-bytes\">Czy pojedynczy element jest typu bytes<\/a><\/li><li><a href=\"#czy-mozna-uzywac-slice-tak-jak-w-listach\">Czy mo\u017cna u\u017cywa\u0107 slice tak jak w listach<\/a><\/li><\/ol><\/li><li><a href=\"#krotkie-zakonczenie-praktyczne\">Kr\u00f3tkie zako\u0144czenie praktyczne<\/a><\/li><\/ol><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"dlaczego-praca-na-bajtach-jest-inna-niz-operacje-na-zwyklych-lancuchach-znakow\">Dlaczego praca na bajtach jest inna ni\u017c operacje na zwyk\u0142ych \u0142a\u0144cuchach znak\u00f3w<\/h2>\n\n\n\n<p>\u0141a\u0144cuch tekstowy <code>str<\/code> opisuje znaki Unicode, czyli warstw\u0119 logiczn\u0105 tekstu. Bajty to warstwa ni\u017csza \u2014 konkretne warto\u015bci od 0 do 255 zapisane w pami\u0119ci lub przesy\u0142ane mi\u0119dzy systemami.<\/p>\n\n\n\n<p>To wa\u017cne rozr\u00f3\u017cnienie. Napis \u201eABC\u201d jako tekst i jako dane binarne nie s\u0105 tym samym obiektem. Tekst wymaga kodowania, na przyk\u0142ad UTF-8, ASCII albo UTF-16. Bajty s\u0105 ju\u017c wynikiem tego kodowania.<\/p>\n\n\n\n<p>Przyk\u0142ad:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>tekst: <code>\"ABC\"<\/code><\/li>\n\n\n\n<li>bajty ASCII: <code>65 66 67<\/code><\/li>\n\n\n\n<li>zapis szesnastkowy: <code>41 42 43<\/code><\/li>\n<\/ul>\n\n\n\n<p>Je\u017celi program czyta nag\u0142\u00f3wek pliku PNG albo pakiet TCP, interesuj\u0105 go konkretne warto\u015bci bajtowe, nie litery.<\/p>\n\n\n\n<p>Typ <code>bytes<\/code> w Pythonie przechowuje sekwencj\u0119 bajt\u00f3w, ale jest niemutowalny. Oznacza to, \u017ce po utworzeniu nie mo\u017cna zmieni\u0107 pojedynczego elementu bez tworzenia nowego obiektu. Przy du\u017cych buforach jest to kosztowne.<\/p>\n\n\n\n<p>Tutaj pojawia si\u0119 <code>bytearray<\/code>, kt\u00f3ry pozwala modyfikowa\u0107 dane w miejscu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bytearray-tworzy-mutowalna-sekwencje-bajtow-i-dlatego-rozni-sie-od-typu-bytes\">bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w i dlatego r\u00f3\u017cni si\u0119 od typu bytes<\/h2>\n\n\n\n<p>Najwa\u017cniejsza cecha tego typu to mutowalno\u015b\u0107. Mo\u017cna zmienia\u0107 elementy, usuwa\u0107 je, dopisywa\u0107 nowe oraz wykonywa\u0107 operacje podobne do pracy na li\u015bcie liczb ca\u0142kowitych.<\/p>\n\n\n\n<p>Ka\u017cdy element jest liczb\u0105 ca\u0142kowit\u0105 z zakresu:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>W\u0142asno\u015b\u0107<\/th><th>Warto\u015b\u0107<\/th><\/tr><\/thead><tbody><tr><td>Minimalna warto\u015b\u0107<\/td><td>0<\/td><\/tr><tr><td>Maksymalna warto\u015b\u0107<\/td><td>255<\/td><\/tr><tr><td>Typ pojedynczego elementu<\/td><td><code>int<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>To oznacza, \u017ce:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dane[0] = 65<\/pre>\n\n\n\n<p>jest poprawne, ale:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dane[0] = 300<\/pre>\n\n\n\n<p>spowoduje b\u0142\u0105d <code>ValueError<\/code>.<\/p>\n\n\n\n<p>Tworzenie obiektu mo\u017cna wykona\u0107 na kilka sposob\u00f3w.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Spos\u00f3b<\/th><th>Przyk\u0142ad<\/th><\/tr><\/thead><tbody><tr><td>Pusty bufor<\/td><td><code>bytearray()<\/code><\/td><\/tr><tr><td>Bufor o zadanym rozmiarze<\/td><td><code>bytearray(10)<\/code><\/td><\/tr><tr><td>Z listy liczb<\/td><td><code>bytearray([65, 66, 67])<\/code><\/td><\/tr><tr><td>Z tekstu i kodowania<\/td><td><code>bytearray(\"ABC\", \"utf-8\")<\/code><\/td><\/tr><tr><td>Z obiektu bytes<\/td><td><code>bytearray(b\"ABC\")<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Warto zauwa\u017cy\u0107, \u017ce <code>bytearray(10)<\/code> nie tworzy liczb od 1 do 10, tylko dziesi\u0119\u0107 bajt\u00f3w o warto\u015bci zero.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"operacje-podstawowe-i-mechanika-dzialania-indeksowania-oraz-modyfikacji-danych\">Operacje podstawowe i mechanika dzia\u0142ania indeksowania oraz modyfikacji danych<\/h2>\n\n\n\n<p><code>bytearray<\/code> zachowuje si\u0119 cz\u0119\u015bciowo jak lista i cz\u0119\u015bciowo jak <code>bytes<\/code>.<\/p>\n\n\n\n<p>Mo\u017cna u\u017cywa\u0107:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>indeksowania<\/li>\n\n\n\n<li>wycink\u00f3w<\/li>\n\n\n\n<li><code>append()<\/code><\/li>\n\n\n\n<li><code>extend()<\/code><\/li>\n\n\n\n<li><code>insert()<\/code><\/li>\n\n\n\n<li><code>pop()<\/code><\/li>\n\n\n\n<li><code>remove()<\/code><\/li>\n\n\n\n<li><code>reverse()<\/code><\/li>\n<\/ul>\n\n\n\n<p>Przyk\u0142ady najlepiej wida\u0107 w prostym zestawieniu.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Operacja<\/th><th>Python<\/th><\/tr><\/thead><tbody><tr><td>Utworzenie<\/td><td><code>bufor = bytearray(b\"ABC\")<\/code><\/td><\/tr><tr><td>Odczyt elementu<\/td><td><code>print(bufor[0])<\/code><\/td><\/tr><tr><td>Zmiana elementu<\/td><td><code>bufor[0] = 90<\/code><\/td><\/tr><tr><td>Dopisanie bajtu<\/td><td><code>bufor.append(68)<\/code><\/td><\/tr><tr><td>Rozszerzenie<\/td><td><code>bufor.extend(b\"EF\")<\/code><\/td><\/tr><tr><td>Usuni\u0119cie<\/td><td><code>bufor.pop()<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Po zmianie:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bufor[0] = 90<\/pre>\n\n\n\n<p>warto\u015b\u0107 <code>65<\/code> zostaje zast\u0105piona przez <code>90<\/code>, czyli znak <code>Z<\/code>.<\/p>\n\n\n\n<p>To jest r\u00f3\u017cnica praktyczna, nie tylko teoretyczna. Przy parsowaniu binarnego protoko\u0142u mo\u017cna poprawi\u0107 fragment danych bez tworzenia nowego obiektu o rozmiarze kilku megabajt\u00f3w.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"przyklady-kodu-w-c-c-i-python-pokazujace-podobna-idee-pracy-na-buforze-bajtowym\">Przyk\u0142ady kodu w C, C++ i Python pokazuj\u0105ce podobn\u0105 ide\u0119 pracy na buforze bajtowym<\/h2>\n\n\n\n<p>Sam <code>bytearray<\/code> jest typem Pythona, ale koncepcja mutowalnego bufora bajtowego istnieje w ka\u017cdym j\u0119zyku.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Przyk\u0142ad<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>bufor = bytearray(b\"ABC\")<\/code><br><code>bufor[1] = 88<\/code><br><code>print(bufor)<\/code><\/td><\/tr><tr><td>C<\/td><td><code>unsigned char bufor[] = {'A','B','C'};<\/code><br><code>bufor[1] = 'X';<\/code><br><code>printf(\"%s\", bufor);<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>std::vector&lt;unsigned char&gt; bufor = {'A','B','C'};<\/code><br><code>bufor[1] = 'X';<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>W C programista zarz\u0105dza pami\u0119ci\u0105 samodzielnie. W Pythonie interpreter robi to automatycznie, ale logika pozostaje podobna: istnieje obszar pami\u0119ci, kt\u00f3rego zawarto\u015b\u0107 mo\u017cna zmienia\u0107.<\/p>\n\n\n\n<p>To w\u0142a\u015bnie sprawia, \u017ce <code>bytearray<\/code> jest naturalny dla os\u00f3b pracuj\u0105cych wcze\u015bniej z C.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bytearray-tworzy-mutowalna-sekwencje-bajtow-podczas-pracy-z-plikami-siecia-i-buforami-danych\">bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w podczas pracy z plikami, sieci\u0105 i buforami danych<\/h2>\n\n\n\n<p>Najcz\u0119stsze zastosowania s\u0105 bardzo praktyczne.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"odczyt-i-modyfikacja-plikow-binarnych\">Odczyt i modyfikacja plik\u00f3w binarnych<\/h3>\n\n\n\n<p>Przy pracy z obrazami, archiwami ZIP, PDF albo w\u0142asnym formatem binarnym cz\u0119sto trzeba zmieni\u0107 pojedynczy bajt nag\u0142\u00f3wka.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Przyk\u0142ad<\/th><th>Python<\/th><\/tr><\/thead><tbody><tr><td>Odczyt pliku<\/td><td><code>with open(\"plik.bin\", \"rb\") as f:<\/code><br>&nbsp;&nbsp;<code>dane = bytearray(f.read())<\/code><\/td><\/tr><tr><td>Modyfikacja<\/td><td><code>dane[0] = 255<\/code><\/td><\/tr><tr><td>Zapis<\/td><td><code>with open(\"nowy.bin\", \"wb\") as f:<\/code><br>&nbsp;&nbsp;<code>f.write(dane)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"bufory-sieciowe\">Bufory sieciowe<\/h3>\n\n\n\n<p>Dane przychodz\u0105ce z gniazda sieciowego nie zawsze s\u0105 kompletne. Cz\u0119sto trzeba budowa\u0107 bufor etapami.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Przyk\u0142ad<\/th><th>Python<\/th><\/tr><\/thead><tbody><tr><td>Bufor sieciowy<\/td><td><code>bufor = bytearray()<\/code><br><code>bufor.extend(sock.recv(1024))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"komunikacja-z-urzadzeniami\">Komunikacja z urz\u0105dzeniami<\/h3>\n\n\n\n<p>Przy UART, SPI, I2C albo komunikacji z mikrokontrolerami cz\u0119sto wysy\u0142a si\u0119 dok\u0142adnie okre\u015blone bajty.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Polecenie<\/th><th>Python<\/th><\/tr><\/thead><tbody><tr><td>Ramka<\/td><td><code>ramka = bytearray([0xAA, 0x01, 0x05, 0xFF])<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Tu nie operuje si\u0119 na tek\u015bcie. Liczy si\u0119 dok\u0142adna warto\u015b\u0107 ka\u017cdego bajtu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"zaleznosc-miedzy-bytes-bytearray-i-pamiecia-programu-podczas-wykonywania-operacji\">Zale\u017cno\u015b\u0107 mi\u0119dzy bytes, bytearray i pami\u0119ci\u0105 programu podczas wykonywania operacji<\/h2>\n\n\n\n<p><code>bytes<\/code> jest niemutowalny, wi\u0119c ka\u017cda zmiana oznacza nowy obiekt.<\/p>\n\n\n\n<p>Schemat wygl\u0105da tak:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Typ<\/th><th>Zachowanie<\/th><\/tr><\/thead><tbody><tr><td><code>bytes<\/code><\/td><td>zmiana = nowy obiekt<\/td><\/tr><tr><td><code>bytearray<\/code><\/td><td>zmiana = modyfikacja istniej\u0105cego obiektu<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Przy ma\u0142ych danych r\u00f3\u017cnica jest niewielka. Przy buforze 100 MB wykonywanym tysi\u0105ce razy dziennie r\u00f3\u017cnica staje si\u0119 kosztowna.<\/p>\n\n\n\n<p>Wydajno\u015b\u0107 zale\u017cy od scenariusza:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>odczyt bez zmian \u2192 cz\u0119sto wystarczy <code>bytes<\/code><\/li>\n\n\n\n<li>cz\u0119ste poprawki \u2192 lepszy <code>bytearray<\/code><\/li>\n\n\n\n<li>budowanie danych etapami \u2192 zwykle <code>bytearray<\/code><\/li>\n<\/ul>\n\n\n\n<p>Nie chodzi wy\u0142\u0105cznie o szybko\u015b\u0107. Chodzi te\u017c o przewidywalno\u015b\u0107 kodu i mniejsz\u0105 liczb\u0119 niepotrzebnych kopii danych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wzory-i-reprezentacje-liczbowe-potrzebne-do-zrozumienia-zapisu-bajtow\">Wzory i reprezentacje liczbowe potrzebne do zrozumienia zapisu bajt\u00f3w<\/h2>\n\n\n\n<p>Programista pracuj\u0105cy z bajtami regularnie spotyka zapis dziesi\u0119tny, binarny i szesnastkowy.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>System<\/th><th>Warto\u015b\u0107 liczby 65<\/th><\/tr><\/thead><tbody><tr><td>Dziesi\u0119tny<\/td><td><code>65<\/code><\/td><\/tr><tr><td>Binarny<\/td><td><code>01000001<\/code><\/td><\/tr><tr><td>Szesnastkowy<\/td><td><code>0x41<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Zakres jednego bajtu wynika z prostego wzoru:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Wz\u00f3r<\/th><th>Znaczenie<\/th><\/tr><\/thead><tbody><tr><td><code>2^8 = 256<\/code><\/td><td>liczba mo\u017cliwych warto\u015bci<\/td><\/tr><tr><td><code>0 ... 255<\/code><\/td><td>realny zakres bajtu<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Dlatego jeden bajt nie przechowa warto\u015bci <code>300<\/code>, ale dwa bajty ju\u017c tak.<\/p>\n\n\n\n<p>To jest istotne przy parsowaniu protoko\u0142\u00f3w i struktur binarnych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bytearray-tworzy-mutowalna-sekwencje-bajtow-a-poprawne-uzycie-zmniejsza-liczbe-bledow-pamieci\">bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w a poprawne u\u017cycie zmniejsza liczb\u0119 b\u0142\u0119d\u00f3w pami\u0119ci<\/h2>\n\n\n\n<p>Najcz\u0119stszy b\u0142\u0105d pocz\u0105tkuj\u0105cych to mieszanie tekstu i bajt\u00f3w.<\/p>\n\n\n\n<p>Nie dzia\u0142a:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bytearray(\"ABC\")<\/pre>\n\n\n\n<p>bo Python wymaga jawnego kodowania.<\/p>\n\n\n\n<p>Poprawnie:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bytearray(\"ABC\", \"utf-8\")<\/pre>\n\n\n\n<p>Drugi problem to pr\u00f3ba wpisania warto\u015bci spoza zakresu.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>B\u0142\u0105d<\/th><th>Skutek<\/th><\/tr><\/thead><tbody><tr><td><code>bufor[0] = 300<\/code><\/td><td><code>ValueError<\/code><\/td><\/tr><tr><td><code>bufor.append(-1)<\/code><\/td><td><code>ValueError<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Trzeci problem to za\u0142o\u017cenie, \u017ce wynik indeksowania zwraca znak.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">print(bufor[0])<\/pre>\n\n\n\n<p>zwraca liczb\u0119 ca\u0142kowit\u0105, nie znak.<\/p>\n\n\n\n<p>Je\u017celi potrzebny jest znak:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">chr(bufor[0])<\/pre>\n\n\n\n<p>albo konwersja ca\u0142ego obiektu:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">bufor.decode(\"utf-8\")<\/pre>\n\n\n\n<p>W praktyce w\u0142a\u015bnie tutaj najcz\u0119\u015bciej traci si\u0119 czas: program dzia\u0142a, ale dane s\u0105 interpretowane nie tak, jak zak\u0142ada autor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-bytearray-jest-szybszy-od-bytes\">Czy bytearray jest szybszy od bytes<\/h3>\n\n\n\n<p>Nie zawsze. Do samego odczytu cz\u0119sto wystarczy <code>bytes<\/code>. Przy cz\u0119stych modyfikacjach <code>bytearray<\/code> zwykle jest lepszy, bo nie wymaga ci\u0105g\u0142ego tworzenia nowych obiekt\u00f3w.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-mozna-zamienic-bytearray-na-bytes\">Czy mo\u017cna zamieni\u0107 bytearray na bytes<\/h3>\n\n\n\n<p>Tak.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Operacja<\/th><th>Python<\/th><\/tr><\/thead><tbody><tr><td>Konwersja<\/td><td><code>wynik = bytes(bufor)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Przydaje si\u0119 to, gdy biblioteka oczekuje dok\u0142adnie typu <code>bytes<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-bytearray-mozna-sortowac\">Czy bytearray mo\u017cna sortowa\u0107<\/h3>\n\n\n\n<p>Technicznie tak, ale w praktyce rzadko ma to sens. Bajty zwykle reprezentuj\u0105 struktur\u0119 danych, a nie warto\u015bci do porz\u0105dkowania.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-bytearray-nadaje-sie-do-duzych-plikow\">Czy bytearray nadaje si\u0119 do du\u017cych plik\u00f3w<\/h3>\n\n\n\n<p>Tak, ale trzeba uwa\u017ca\u0107 na pami\u0119\u0107 RAM. Wczytanie ca\u0142ego pliku 2 GB nadal oznacza potrzeb\u0119 posiadania odpowiedniej ilo\u015bci pami\u0119ci operacyjnej.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-pojedynczy-element-jest-typu-bytes\">Czy pojedynczy element jest typu bytes<\/h3>\n\n\n\n<p>Nie. Jest typu <code>int<\/code>, czyli liczb\u0105 od 0 do 255.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-mozna-uzywac-slice-tak-jak-w-listach\">Czy mo\u017cna u\u017cywa\u0107 slice tak jak w listach<\/h3>\n\n\n\n<p>Tak.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Operacja<\/th><th>Python<\/th><\/tr><\/thead><tbody><tr><td>Fragment bufora<\/td><td><code>fragment = bufor[2:8]<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>To bardzo wygodne przy analizie nag\u0142\u00f3wk\u00f3w plik\u00f3w i ramek sieciowych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"krotkie-zakonczenie-praktyczne\">Kr\u00f3tkie zako\u0144czenie praktyczne<\/h2>\n\n\n\n<p><code>bytearray<\/code> nie jest egzotycznym dodatkiem do j\u0119zyka, tylko narz\u0119dziem potrzebnym wsz\u0119dzie tam, gdzie program styka si\u0119 z rzeczywistymi danymi binarnymi. Im wcze\u015bniej programista nauczy si\u0119 rozr\u00f3\u017cnia\u0107 tekst od bajt\u00f3w, tym mniej czasu straci p\u00f3\u017aniej na b\u0142\u0119dy zwi\u0105zane z kodowaniem, kopiowaniem pami\u0119ci i nieczytelnym debugowaniem. Przy pracy z plikami, protoko\u0142ami i urz\u0105dzeniami ten typ staje si\u0119 po prostu codziennym narz\u0119dziem.<\/p>\n\n\n\n<p><em>\u0179r\u00f3d\u0142o Foto: Freepik<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Praca na danych binarnych pojawia si\u0119 szybciej, ni\u017c zwykle zak\u0142ada pocz\u0105tkuj\u0105cy programista. Odczyt plik\u00f3w, komunikacja po sieci, analiza ramek protoko\u0142\u00f3w, operacje na obrazach, archiwach czy danych z urz\u0105dze\u0144 \u2013 wsz\u0119dzie tam operujemy nie na znakach, ale na bajtach. R\u00f3\u017cnica mi\u0119dzy obiektem niemodyfikowalnym a takim, kt\u00f3ry mo\u017cna zmienia\u0107 w miejscu, ma wtedy realne znaczenie dla wydajno\u015bci i czytelno\u015bci kodu. W Pythonie w\u0142a\u015bnie do tego s\u0142u\u017cy bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w. Dlaczego praca na bajtach jest inna ni\u017c operacje na zwyk\u0142ych \u0142a\u0144cuchach znak\u00f3w \u0141a\u0144cuch tekstowy str opisuje znaki Unicode, czyli warstw\u0119 logiczn\u0105 tekstu. Bajty to warstwa ni\u017csza \u2014 konkretne warto\u015bci od 0 do 255 zapisane w pami\u0119ci lub przesy\u0142ane mi\u0119dzy systemami. To wa\u017cne rozr\u00f3\u017cnienie. Napis \u201eABC\u201d jako tekst i jako dane binarne nie s\u0105 tym samym obiektem. Tekst wymaga kodowania, na przyk\u0142ad UTF-8, ASCII albo UTF-16. Bajty s\u0105 ju\u017c wynikiem tego kodowania. Przyk\u0142ad: Je\u017celi program czyta nag\u0142\u00f3wek pliku PNG albo pakiet TCP, interesuj\u0105 go konkretne warto\u015bci bajtowe, nie litery. Typ bytes w Pythonie przechowuje sekwencj\u0119 bajt\u00f3w, ale jest niemutowalny. Oznacza to, \u017ce po utworzeniu nie mo\u017cna zmieni\u0107 pojedynczego elementu bez tworzenia nowego obiektu. Przy du\u017cych buforach jest to kosztowne. Tutaj pojawia si\u0119 bytearray, kt\u00f3ry pozwala modyfikowa\u0107 dane w miejscu. bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w i dlatego r\u00f3\u017cni si\u0119 od typu bytes Najwa\u017cniejsza cecha tego typu to mutowalno\u015b\u0107. Mo\u017cna zmienia\u0107 elementy, usuwa\u0107 je, dopisywa\u0107 nowe oraz wykonywa\u0107 operacje podobne do pracy na li\u015bcie liczb ca\u0142kowitych. Ka\u017cdy element jest liczb\u0105 ca\u0142kowit\u0105 z zakresu: W\u0142asno\u015b\u0107 Warto\u015b\u0107 Minimalna warto\u015b\u0107 0 Maksymalna warto\u015b\u0107 255 Typ pojedynczego elementu int To oznacza, \u017ce: dane[0] = 65 jest poprawne, ale: dane[0] = 300 spowoduje b\u0142\u0105d ValueError. Tworzenie obiektu mo\u017cna wykona\u0107 na kilka sposob\u00f3w. Spos\u00f3b Przyk\u0142ad Pusty bufor bytearray() Bufor o zadanym rozmiarze bytearray(10) Z listy liczb bytearray([65, 66, 67]) Z tekstu i kodowania bytearray(&#8222;ABC&#8221;, &#8222;utf-8&#8243;) Z obiektu bytes bytearray(b&#8221;ABC&#8221;) Warto zauwa\u017cy\u0107, \u017ce bytearray(10) nie tworzy liczb od 1 do 10, tylko dziesi\u0119\u0107 bajt\u00f3w o warto\u015bci zero. Operacje podstawowe i mechanika dzia\u0142ania indeksowania oraz modyfikacji danych bytearray zachowuje si\u0119 cz\u0119\u015bciowo jak lista i cz\u0119\u015bciowo jak bytes. Mo\u017cna u\u017cywa\u0107: Przyk\u0142ady najlepiej wida\u0107 w prostym zestawieniu. Operacja Python Utworzenie bufor = bytearray(b&#8221;ABC&#8221;) Odczyt elementu print(bufor[0]) Zmiana elementu bufor[0] = 90 Dopisanie bajtu bufor.append(68) Rozszerzenie bufor.extend(b&#8221;EF&#8221;) Usuni\u0119cie bufor.pop() Po zmianie: bufor[0] = 90 warto\u015b\u0107 65 zostaje zast\u0105piona przez 90, czyli znak Z. To jest r\u00f3\u017cnica praktyczna, nie tylko teoretyczna. Przy parsowaniu binarnego protoko\u0142u mo\u017cna poprawi\u0107 fragment danych bez tworzenia nowego obiektu o rozmiarze kilku megabajt\u00f3w. Przyk\u0142ady kodu w C, C++ i Python pokazuj\u0105ce podobn\u0105 ide\u0119 pracy na buforze bajtowym Sam bytearray jest typem Pythona, ale koncepcja mutowalnego bufora bajtowego istnieje w ka\u017cdym j\u0119zyku. J\u0119zyk Przyk\u0142ad Python bufor = bytearray(b&#8221;ABC&#8221;)bufor[1] = 88print(bufor) C unsigned char bufor[] = {&#8217;A&#8217;,&#8217;B&#8217;,&#8217;C&#8217;};bufor[1] = 'X&#8217;;printf(&#8222;%s&#8221;, bufor); C++ std::vector&lt;unsigned char&gt; bufor = {&#8217;A&#8217;,&#8217;B&#8217;,&#8217;C&#8217;};bufor[1] = 'X&#8217;; W C programista zarz\u0105dza pami\u0119ci\u0105 samodzielnie. W Pythonie interpreter robi to automatycznie, ale logika pozostaje podobna: istnieje obszar pami\u0119ci, kt\u00f3rego zawarto\u015b\u0107 mo\u017cna zmienia\u0107. To w\u0142a\u015bnie sprawia, \u017ce bytearray jest naturalny dla os\u00f3b pracuj\u0105cych wcze\u015bniej z C. bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w podczas pracy z plikami, sieci\u0105 i buforami danych Najcz\u0119stsze zastosowania s\u0105 bardzo praktyczne. Odczyt i modyfikacja plik\u00f3w binarnych Przy pracy z obrazami, archiwami ZIP, PDF albo w\u0142asnym formatem binarnym cz\u0119sto trzeba zmieni\u0107 pojedynczy bajt nag\u0142\u00f3wka. Przyk\u0142ad Python Odczyt pliku with open(&#8222;plik.bin&#8221;, &#8222;rb&#8221;) as f:&nbsp;&nbsp;dane = bytearray(f.read()) Modyfikacja dane[0] = 255 Zapis with open(&#8222;nowy.bin&#8221;, &#8222;wb&#8221;) as f:&nbsp;&nbsp;f.write(dane) Bufory sieciowe Dane przychodz\u0105ce z gniazda sieciowego nie zawsze s\u0105 kompletne. Cz\u0119sto trzeba budowa\u0107 bufor etapami. Przyk\u0142ad Python Bufor sieciowy bufor = bytearray()bufor.extend(sock.recv(1024)) Komunikacja z urz\u0105dzeniami Przy UART, SPI, I2C albo komunikacji z mikrokontrolerami cz\u0119sto wysy\u0142a si\u0119 dok\u0142adnie okre\u015blone bajty. Polecenie Python Ramka ramka = bytearray([0xAA, 0x01, 0x05, 0xFF]) Tu nie operuje si\u0119 na tek\u015bcie. Liczy si\u0119 dok\u0142adna warto\u015b\u0107 ka\u017cdego bajtu. Zale\u017cno\u015b\u0107 mi\u0119dzy bytes, bytearray i pami\u0119ci\u0105 programu podczas wykonywania operacji bytes jest niemutowalny, wi\u0119c ka\u017cda zmiana oznacza nowy obiekt. Schemat wygl\u0105da tak: Typ Zachowanie bytes zmiana = nowy obiekt bytearray zmiana = modyfikacja istniej\u0105cego obiektu Przy ma\u0142ych danych r\u00f3\u017cnica jest niewielka. Przy buforze 100 MB wykonywanym tysi\u0105ce razy dziennie r\u00f3\u017cnica staje si\u0119 kosztowna. Wydajno\u015b\u0107 zale\u017cy od scenariusza: Nie chodzi wy\u0142\u0105cznie o szybko\u015b\u0107. Chodzi te\u017c o przewidywalno\u015b\u0107 kodu i mniejsz\u0105 liczb\u0119 niepotrzebnych kopii danych. Wzory i reprezentacje liczbowe potrzebne do zrozumienia zapisu bajt\u00f3w Programista pracuj\u0105cy z bajtami regularnie spotyka zapis dziesi\u0119tny, binarny i szesnastkowy. System Warto\u015b\u0107 liczby 65 Dziesi\u0119tny 65 Binarny 01000001 Szesnastkowy 0x41 Zakres jednego bajtu wynika z prostego wzoru: Wz\u00f3r Znaczenie 2^8 = 256 liczba mo\u017cliwych warto\u015bci 0 &#8230; 255 realny zakres bajtu Dlatego jeden bajt nie przechowa warto\u015bci 300, ale dwa bajty ju\u017c tak. To jest istotne przy parsowaniu protoko\u0142\u00f3w i struktur binarnych. bytearray \u2013 tworzy mutowaln\u0105 sekwencj\u0119 bajt\u00f3w a poprawne u\u017cycie zmniejsza liczb\u0119 b\u0142\u0119d\u00f3w pami\u0119ci Najcz\u0119stszy b\u0142\u0105d pocz\u0105tkuj\u0105cych to mieszanie tekstu i bajt\u00f3w. Nie dzia\u0142a: bytearray(&#8222;ABC&#8221;) bo Python wymaga jawnego kodowania. Poprawnie: bytearray(&#8222;ABC&#8221;, &#8222;utf-8&#8221;) Drugi problem to pr\u00f3ba wpisania warto\u015bci spoza zakresu. B\u0142\u0105d Skutek bufor[0] = 300 ValueError bufor.append(-1) ValueError Trzeci problem to za\u0142o\u017cenie, \u017ce wynik indeksowania zwraca znak. print(bufor[0]) zwraca liczb\u0119 ca\u0142kowit\u0105, nie znak. Je\u017celi potrzebny jest znak: chr(bufor[0]) albo konwersja ca\u0142ego obiektu: bufor.decode(&#8222;utf-8&#8221;) W praktyce w\u0142a\u015bnie tutaj najcz\u0119\u015bciej traci si\u0119 czas: program dzia\u0142a, ale dane s\u0105 interpretowane nie tak, jak zak\u0142ada autor. FAQ Czy bytearray jest szybszy od bytes Nie zawsze. Do samego odczytu cz\u0119sto wystarczy bytes. Przy cz\u0119stych modyfikacjach bytearray zwykle jest lepszy, bo nie wymaga ci\u0105g\u0142ego tworzenia nowych obiekt\u00f3w. Czy mo\u017cna zamieni\u0107 bytearray na bytes Tak. Operacja Python Konwersja wynik = bytes(bufor) Przydaje si\u0119 to, gdy biblioteka oczekuje dok\u0142adnie typu bytes. Czy bytearray mo\u017cna sortowa\u0107 Technicznie tak, ale w praktyce rzadko ma to sens. Bajty zwykle reprezentuj\u0105 struktur\u0119 danych, a nie warto\u015bci do porz\u0105dkowania. Czy bytearray nadaje si\u0119 do du\u017cych plik\u00f3w Tak, ale trzeba uwa\u017ca\u0107 na pami\u0119\u0107 RAM. Wczytanie ca\u0142ego pliku 2 GB nadal oznacza potrzeb\u0119 posiadania odpowiedniej ilo\u015bci pami\u0119ci operacyjnej. Czy pojedynczy element jest typu bytes Nie. Jest typu int, czyli liczb\u0105 od 0 do 255. Czy mo\u017cna u\u017cywa\u0107 slice tak jak w listach Tak. Operacja Python Fragment bufora fragment = bufor[2:8] To bardzo wygodne przy analizie nag\u0142\u00f3wk\u00f3w plik\u00f3w i ramek sieciowych. Kr\u00f3tkie zako\u0144czenie praktyczne bytearray nie jest egzotycznym dodatkiem do j\u0119zyka, tylko narz\u0119dziem potrzebnym wsz\u0119dzie tam, gdzie program styka si\u0119 z rzeczywistymi danymi binarnymi. Im wcze\u015bniej programista nauczy si\u0119 rozr\u00f3\u017cnia\u0107 tekst od bajt\u00f3w, tym mniej czasu straci p\u00f3\u017aniej na b\u0142\u0119dy zwi\u0105zane z kodowaniem, kopiowaniem pami\u0119ci i nieczytelnym debugowaniem. Przy pracy z plikami, protoko\u0142ami i urz\u0105dzeniami ten typ staje si\u0119 po prostu codziennym narz\u0119dziem. \u0179r\u00f3d\u0142o Foto: Freepik<\/p>\n","protected":false},"author":1,"featured_media":1430,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[],"class_list":["post-1429","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kodowanie"],"_links":{"self":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1429","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1429"}],"version-history":[{"count":1,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1429\/revisions"}],"predecessor-version":[{"id":1431,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1429\/revisions\/1431"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media\/1430"}],"wp:attachment":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}