Wprowadzenie

W tym artykule przyjrzymy się, jak przekonwertować bajty na łańcuchy w Pythonie. Do końca tego artykułu będziesz miał jasne pojęcie, czym są te typy i jak efektywnie operować na danych przy ich użyciu.

W zależności od wersji Pythona, której używasz, zadanie to będzie się różnić. Chociaż Python 2 osiągnął swój kres życia, wiele projektów nadal go używa, więc uwzględnimy zarówno podejście Pythona 2, jak i Pythona 3.

Konwersja bajtów na łańcuchy w Pythonie 3

Od Pythona 3 stary sposób robienia rzeczy w ASCII musiał odejść, a Python stał się całkowicie Unicode.

To oznacza, że straciliśmy jawne typy Unicode: u"string" – każdy ciąg znaków jest u"string"!

Aby odróżnić te ciągi od starych dobrych bajtstringów, wprowadzono dla nich nowy specyfikator – b"string".

To zostało dodane w Pythonie 2.6, ale nie służyło to żadnemu prawdziwemu celowi poza przygotowaniem do Pythona 3, ponieważ wszystkie ciągi były bajtostringami w 2.6.

Bytestringi w Pythonie 3 są oficjalnie nazywane bytes, niezmienną sekwencją liczb całkowitych w zakresie 0 <= x < 256. Kolejnym bytespodobnym obiektem dodanym w 2.6 jest bytearray – podobny do bytes, ale mutowalny.

Konwersja bajtów na String za pomocą decode()

Przyjrzyjrzyjmy się, jak możemy przekonwertować bajty na String, używając wbudowanej metody decode() dla klasy bytes:

Przechodząc przez format kodowania, zdekodowaliśmy obiekt bytes do stringa i wydrukowaliśmy go.

Konwersja bajtów na ciąg znaków za pomocą kodeków

Alternatywnie, możemy do tego celu użyć również wbudowanego modułu codecs:

>>> import codecs>>> b = b'Lets grab a \xf0\x9f\x8d\x95!'>>> codecs.decode(b, 'UTF-8')"Let's grab a 🍕!"

Nie musisz tak naprawdę przekazywać parametru kodowania, choć zaleca się jego przekazanie:

>>> codecs.decode(b)"Let's grab a 🍕!"

Convert Bytes to String with str()

Na koniec można skorzystać z funkcji str() , która przyjmuje różne wartości i konwertuje je na ciągi znaków:

>>> b = b'Lets grab a \xf0\x9f\x8d\x95!'>>> str(b, 'UTF-8')"Let's grab a 🍕!"

Pamiętaj jednak, aby podać argument encoding do str() chociaż, w przeciwnym razie możesz otrzymać pewne nieoczekiwane wyniki:

>>> str(b)b'Lets grab a \xf0\x9f\x8d\x95!'

To sprowadza nas do kodowania po raz kolejny. Jeśli podasz niewłaściwe kodowanie, w najlepszym wypadku Twój program zawiesi się, ponieważ nie będzie w stanie zdekodować danych. Na przykład, jeśli spróbujemy użyć funkcji str() z UTF-16, zostaniemy przywitani przez:

>>> str(b, 'UTF-16')'敌❴\u2073牧扡愠\uf020趟↕'

Jest to tym ważniejsze, że Python 3 lubi zakładać Unicode – więc jeśli pracujesz z plikami lub źródłami danych, które używają niejasnego kodowania, upewnij się, że zwracasz na to dodatkową uwagę.

Konwersja bajtów na ciągi w Pythonie 2

W Pythonie 2 wiązka bajtów i ciąg znaków to praktycznie to samo – ciągi są obiektami składającymi się z jednobajtowych znaków, co oznacza, że każdy znak może przechowywać 256 wartości. Z tego powodu są one czasami nazywane bytestringami.

Jest to świetne rozwiązanie, gdy pracujemy z danymi bajtowymi – po prostu ładujemy je do zmiennej i jesteśmy gotowi do drukowania:

>>> s = "Hello world!">>> s'Hello world!'>>> len(s)12

Używanie znaków Unicode w bytestringach zmienia jednak nieco to zachowanie:

>>> s = "Let's grab a 🍕!">>> s'Lets grab a \xf0\x9f\x8d\x95!'# Where has the pizza gone to?>>> len(s)17# Shouldn't that be 15?

Konwersja bajtów do Unicode (Python 2)

W tym miejscu będziemy musieli użyć typu Pythona 2 Unicode, który jest zakładany i automatycznie używany w Pythonie 3. Przechowuje on ciągi znaków jako serię punktów kodowych, a nie bajtów.

Typ \xf0\x9f\x8d\x95 reprezentuje bajty jako dwucyfrowe liczby heksadecymalne, ponieważ Python nie wie, jak reprezentować je jako znaki ASCII:

>>> u = u"Let's grab a 🍕!"u"Let's grab a \U0001f355!"">>> u"Let's grab a 🍕!"# Yum.>>> len(u)15

Jak widać powyżej, łańcuch Unicode zawiera \U0001f355 – znak ucieczki Unicode, który nasz terminal wie teraz, jak wydrukować jako kawałek pizzy! Ustawienie tego było tak proste, jak użycie specyfikatora u przed wartością bytestringa.

Więc, jak mogę przełączać się pomiędzy tymi dwoma?

Możesz uzyskać łańcuch Unicode poprzez dekodowanie twojego bytestringa. Można to zrobić, konstruując obiekt Unicode, przekazując bytestring i łańcuch zawierający nazwę kodowania jako argumenty lub wywołując .decode(encoding) na bytestringu.

Konwersja bajtów na ciąg znaków za pomocą funkcji decode() (Python 2)

Możesz również użyć funkcji codecs.encode(s, encoding) z modułu codecs.

>>> s = "Let's grab a \xf0\x9f\x8d\x95!">>> u = unicode(s, 'UTF-8')>>> u"Let's grab a 🍕!">>> s.decode('UTF-8')"Let's grab a 🍕!"

Convert Bytes to String Using codecs (Python 2)

Or, używając modułu codecs:

import codecs>>> codecs.decode(s, 'UTF-8')"Let's grab a 🍕!"

Be Mindful of your Encoding

Słowo ostrożności tutaj – bajty mogą być interpretowane inaczej w różnych kodowaniach. Z około 80 różnymi kodowaniami dostępnymi po wyjęciu z pudełka, może nie być łatwo wiedzieć, czy masz właściwy!

Oryginalna wiadomość była albo øç lub јч, i oba wydają się być poprawnymi konwersjami.

Wnioski

Jako programiści, są pewne rzeczy, o których musimy stale myśleć i aktywnie się przygotowywać, aby uniknąć pułapek. Jest to szczególnie prawdziwe na niższych poziomach, gdzie rzadko się zapuszczamy, gdy używamy języka wysokiego poziomu, takiego jak Python, jako naszego codziennego kierowcy.

Rzeczy takie jak zestawy znaków, kodowanie i binarność przypominają nam, że naszym zadaniem jest kodowanie – kodowanie naszych myśli w działające rozwiązania. Na szczęście, wiele z tego myślenia staje się częścią naszej rutyny po kilku rundach przy klawiaturze.

W tym artykule omówiliśmy, jak konwertować bajty na ciągi w Pythonie.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *