Bajtová pole jsou proměnnýsekvenční datový typ, jehož prvky jsou celá čísla v rozmezí <0, 255> (tedy vlastně sekvence bajtů).
Existuje k nim i příslušný neproměnný protějšek – bajtové řetězce. Rozdíl mezi těmito dvěma objekty je podobný, jako mezi řetězci na jedné straně a seznamy znaků na straně druhé – oboje vypsané po prvcích dá to samé, ale do řetězců nemůžeme „hrabat“, zatímco se seznamy si můžeme dělat, co chceme.
Bajtová pole zavádíme konstruktorem bytearray(). Pro jeho parametry platí úplně to samé, co pro paramatry konstruktoru bajtových řetězcůbytes(), to znamená:
Při volání bez parametru zavede funkce bytearray() bajtové pole o nulové délce:
>>> xb = bytearray()
>>> xb
bytearray(b'')
Je-li vstupním parametrem řetězec, musíme navíc přidat i kódování, které bude řídit jeho transformaci na bajtové pole:
>>> xb = bytearray('Ahoj!', 'utf-8')
>>> xb
bytearray(b'Ahoj!')
Na pozadí se zavolá metoda řetězce 'Ahoj!'.encode('utf-8'), která provede příslušnou konverzi.
Při vstupním parametru celé číslo je vytvořeno bajtové pole odpovídající délky obsahující samé nuly:
Další možností je zadat na vstupu iterovatelný objekt (iterable), který vrací čísla v rozmezí <0, 255>. Tato čísla budou následně použita pro inicializaci (bajtového) pole.
Pokud byste potřebovali převést jedno konkrétní číslo na jednoprvkové bajtové pole, kód bytearray([123]) nepřekvapivě vrátí právě bytearray(b'{'). (Dělat konverzi z bytes na bytearray jde samozřejmě také, ale je to tuplovaně nešikovné.)
Poslední možností je použít na vstupu bafr (buffer), v klasickém případě tedy odkaz na otevřený soubor. V takovém případě se pro inicializaci bajtového pole použijí data (jednotlivé bajty) z bafru.
Bajtová pole podporují standardní operace, jaké bychom u proměnného typu čekali (v podstatě se chovají jako seznamy bajtů):
>>> xb = bytearray(b'ahoj')
# délka sekvence
>>> len(xb)
4
# konkrétní prvek
>>> xb[3]
106
>>> xb[-3]
104
# různé výřezy
>>> xb[1:3]
bytearray(b'ho')
>>> xb[1::2]
bytearray(b'hj')
>>> xb[2:]
bytearray(b'oj')
>>> xb[-3:]
bytearray(b'hoj')
# dotaz na výskyt prvku
>>> 111 in xb
True
>>> 110 in xb
False
>>> b'a' in xb
True
>>> b'\xf1' in xb
False
>>> xb.index(b'h')
1
>>> xb.index(b'D')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: subsection not found
>>> xb.count(b'a')
1
# dvě spojené kopie
>>> xb * 2
bytearray(b'ahojahoj')
Stejně tak máme k dispozici tradiční procházení smyčkou for-in ve všech jejích podobách:
>>> xb = bytearray(b'ahoj')
>>> for x in xb:
... print(x)
...
97
104
111
106
>>> for i, x in enumerate(xb):
... print(i, x)
...
0 97
1 104
2 111
3 106
>>> for x in reversed(xb):
... print(x)
...
106
111
104
97
>>> for x in sorted(xb):
... print(x)
...
97
104
106
111
Hlavním důvodem pro použití bajtových polí je to, že narozdíl od bajtových řetězců je můžeme měnit ^_~
Rozšíření pole o dané bajty pomocí metody extend(BAJTY), resp. pomocí operátoru +:
>>> xb = bytearray(b'Ahoj')
# a) metodou
>>> xb.extend(b', svete!')
>>> xb
bytearray(b'Ahoj, svete!')
# b) operátorově
>>> xb + b' Jak se mas?'
bytearray(b'Ahoj, svete! Jak se mas?')
Nenechte se zmást tím, že ukázky ukazuji na cestine. Je to jenom proto, že se to čte líp než nějaké sekvence netisknutelných bajtů.
Prvky z bajtového pole odstraňujeme pomocí stejných metod jako u seznamů, tzn.:
Pomocí univerzálního příkazu del:
>>> xb = bytearray(b'Ahoj, svete! Jak se mas?')
>>> del xb[-1]
>>> xb
bytearray(b'Ahoj, svete! Jak se mas')
>>> del xb[4:]
>>> xb
bytearray(b'Ahoj')
Pomocí metody pop([INDEX]), která navíc vrací odebraný prvek:
>>> xb = bytearray(b'Ahoj, svete! Jak se mas?')
>>> xb.pop()
63
>>> xb
bytearray(b'Ahoj, svete! Jak se mas')
>>> xb.pop(0)
65
>>> xb
bytearray(b'hoj, svete! Jak se mas')
Pokus o odstranění prvku na neexistující pozici nebo z prázdného bajtového pole skončí výjimkou IndexError.
Pomocí metody remove(PRVEK), která odstraní první výskyt (zleva) příslušného prvku:
>>> xb = bytearray(b'Ahoj, svete! Jak se mas?')
>>> xb.remove(101)
>>> xb
bytearray(b'Ahoj, svte! Jak se mas?')
>>> xb.remove(100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: value not found in bytearray
Opět: Nenechte se zmást tím, že ukázky ukazuji na cestine. Je to jenom proto, že se to čte líp než nějaké sekvence netisknutelných bajtů.