Pracuję z biblioteką, która zwraca ciąg bajtów i muszę go przekonwertować na ciąg.
Chociaż nie jestem pewien, jaka jest różnica - jeśli w ogóle.
Zakładając, że Python 3 (w Pythonie 2 ta różnica jest nieco mniej dobrze zdefiniowana) - ciąg znaków jest sekwencją znaków, tj. Punktami kodowymi Unicode ; są to abstrakcyjne pojęcia i nie mogą być bezpośrednio przechowywane na dysku. Ciąg bajtów to sekwencja bajtów - rzeczy, które można przechowywać na dysku. Mapowanie między nimi jest kodowaniem - jest ich całkiem sporo (i nieskończenie wiele jest możliwych) - i musisz wiedzieć, które mają zastosowanie w danym przypadku, aby wykonać konwersję, ponieważ inne kodowanie może odwzorować te same bajty do innego ciągu:
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16')
'蓏콯캁澽苏'
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8')
'τoρνoς'
Kiedy już wiesz, którego użyć, możesz użyć .decode()
metody ciągu bajtów, aby uzyskać z niego odpowiedni ciąg znaków, jak wyżej. Dla kompletności .encode()
metoda ciągu znaków przebiega w drugą stronę:
>>> 'τoρνoς'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'
str
typ jest taki sam jakbytes
typ; ta odpowiedź w sposób równoważny porównujeunicode
typ (nie istnieje w Pythonie 3) zstr
typem.str
nie jest dostępna ani istotna ze strony Pythona; struktura danych jest tylko sekwencją punktów kodowych. Zgodnie z PEP 393 , dokładne kodowanie wewnętrzne to Latin-1, UCS2 lub UCS4, a reprezentacja utf-8 może być buforowana po pierwszym żądaniu, ale nawet kod C nie jest zależny od tych wewnętrznych szczegółów.Jedyne, co komputer może przechowywać, to bajty.
Aby zapisać cokolwiek w komputerze, musisz najpierw go zakodować , tzn. Przekonwertować na bajty. Na przykład:
MP3
,WAV
itdPNG
,JPEG
itdASCII
,UTF-8
itdMP3
,WAV
,PNG
,JPEG
,ASCII
IUTF-8
przedstawiono przykłady kodowania . Kodowanie to format reprezentujący audio, obrazy, tekst itp. W bajtach.W Pythonie ciąg bajtów jest po prostu: sekwencją bajtów. Nie jest czytelny dla człowieka. Pod maską wszystko musi zostać przekonwertowane na ciąg bajtów, zanim będzie można je zapisać na komputerze.
Z drugiej strony ciąg znaków, często nazywany po prostu „ciągiem”, jest ciągiem znaków. Jest czytelny dla człowieka. Ciąg znaków nie może być bezpośrednio zapisany na komputerze, musi być najpierw zakodowany (przekształcony w ciąg bajtów). Istnieje wiele kodowań, za pomocą których ciąg znaków można przekonwertować na ciąg bajtów, takich jak
ASCII
iUTF-8
.Powyższy kod Python koduje ciąg
'I am a string'
przy użyciu kodowaniaASCII
. Wynikiem powyższego kodu będzie ciąg bajtów. Jeśli go wydrukujesz, Python będzie go reprezentował jakob'I am a string'
. Pamiętaj jednak, że ciągi bajtów nie są czytelne dla człowieka , po prostu Python dekoduje jeASCII
podczas drukowania. W Pythonie ciąg bajtów jest reprezentowany przez ab
, po którym następuje reprezentacja ciągu bajtówASCII
.Łańcuch bajtów może zostać zdekodowany z powrotem na ciąg znaków, jeśli znasz kodowanie użyte do jego zakodowania.
Powyższy kod zwróci oryginalny ciąg
'I am a string'
.Kodowanie i dekodowanie to operacje odwrotne. Wszystko musi zostać zakodowane, zanim będzie mogło zostać zapisane na dysk, i musi zostać odkodowane, zanim będzie mogło być odczytane przez człowieka.
źródło
Uwaga: Bardziej szczegółowo opracuję moją odpowiedź dla Python 3, ponieważ koniec życia Python 2 jest bardzo bliski.
W Python 3
bytes
składa się z sekwencji 8-bitowych wartości bez znaku, natomiaststr
składa się z sekwencji punktów kodu Unicode reprezentujących znaki tekstowe z języków ludzkich.Mimo że
bytes
istr
wydają się działać w ten sam sposób, ich instancje nie są ze sobą kompatybilne, tj.bytes
Istr
instancji nie można używać razem z operatorami takimi jak>
i+
. Ponadto należy pamiętać, że porównywaniebytes
istr
przypadki równości, tj. Używanie==
, zawsze będą oceniać,False
nawet jeśli zawierają dokładnie te same znaki.Kolejny problem związany z obsługą
bytes
istr
występujący podczas pracy z plikami zwracanymi za pomocąopen
wbudowanej funkcji. Z jednej strony, jeśli chcesz czytać lub zapisywać dane binarne do / z pliku, zawsze otwieraj plik w trybie binarnym, takim jak „rb” lub „wb”. Z drugiej strony, jeśli chcesz czytać lub zapisywać dane Unicode do / z pliku, pamiętaj o domyślnym kodowaniu komputera, więc w razie potrzeby przekażencoding
parametr, aby uniknąć niespodzianek.W Python 2
str
składa się z sekwencji 8-bitowych wartości, aunicode
składa się z sekwencji znaków Unicode. Należy pamiętać o tymstr
iunicode
można go używać razem z operatorami, jeślistr
składa się tylko z 7-bitowych znaków ASCI.Przydatne może być użycie funkcji pomocniczych do konwersji pomiędzy
str
iunicode
w Pythonie 2 oraz pomiędzybytes
istr
w Pythonie 3.źródło
Z Co to jest Unicode :
Kiedy więc komputer reprezentuje ciąg znaków, znajduje znaki zapisane na komputerze ciągu dzięki unikalnemu numerowi Unicode, a liczby te są przechowywane w pamięci. Ale nie można bezpośrednio napisać łańcucha na dysk ani przesłać go w sieci za pomocą jego unikalnego numeru Unicode, ponieważ liczby te są po prostu zwykłą liczbą dziesiętną. Należy zakodować ciąg do ciągu bajtowego, na przykład
UTF-8
.UTF-8
to postać kodowania zdolne do kodowania wszystkich możliwych znaków i przechowuje znaki jako bajty (wygląda jak ten ). Tak więc zakodowany ciąg może być używany wszędzie, ponieważUTF-8
jest prawie wszędzie obsługiwany. Po otwarciu pliku tekstowego zakodowanego wUTF-8
z innych systemów komputer go dekoduje i wyświetla w nim znaki za pomocą unikalnego numeru Unicode. Gdy przeglądarka odbiera dane łańcucha zakodowaneUTF-8
z sieci, dekoduje dane do łańcucha (zakładając, że przeglądarkaUTF-8
koduje) i wyświetla ciąg.W python3 możesz transformować ciąg znaków i bajtów na siebie:
Jednym słowem, ciąg znaków służy do wyświetlania ludziom do odczytu na komputerze, a ciąg bajtów służy do przechowywania na dysku i transmisji danych.
źródło
Unicode jest uzgodnionym formatem binarnej reprezentacji znaków i różnego rodzaju formatowania (np. Małe / wielkie litery, nowa linia, znak powrotu karetki) i innych „rzeczy” (np. Emoji). Komputer jest nie mniej zdolny do przechowywania reprezentacji Unicode (seria bitów), czy to w pamięci, czy w pliku, niż do przechowywania reprezentacji ascii (inna seria bitów) lub jakiejkolwiek innej reprezentacji (seria bitów ).
Aby komunikacja mogła się odbyć, strony komunikacji muszą uzgodnić, jaką reprezentację należy zastosować.
Ponieważ Unicode stara się reprezentować wszystkie możliwe znaki (i inne „rzeczy”) używane w komunikacji między ludźmi i między komputerami, wymaga większej liczby bitów do przedstawienia wielu znaków (lub rzeczy) niż inne systemy reprezentacji, które starają się reprezentować bardziej ograniczony zestaw znaków / rzeczy. Aby „uprościć” i być może dostosować do użycia w przeszłości, reprezentacja Unicode jest prawie wyłącznie konwertowana na inny system reprezentacji (np. Ascii) w celu przechowywania znaków w plikach.
Nie jest tak, że Unicode nie może być używane do przechowywania znaków w plikach lub przesyłania ich jakimkolwiek kanałem komunikacyjnym, po prostu tak nie jest .
Termin „ciąg znaków” nie jest dokładnie zdefiniowany. „Ciąg znaków” w swoim powszechnym użyciu odnosi się do zestawu znaków / rzeczy. Na komputerze znaki te mogą być przechowywane w dowolnej z wielu różnych reprezentacji krok po kroku. „Łańcuch bajtów” to zestaw znaków przechowywanych przy użyciu reprezentacji, która wykorzystuje osiem bitów (osiem bitów nazywanych jest bajtem). Ponieważ w dzisiejszych czasach komputery używają systemu Unicode (znaki reprezentowane przez zmienną liczbę bajtów) do przechowywania znaków w pamięci, a ciągi bajtów (znaki reprezentowane przez pojedyncze bajty) do przechowywania znaków w plikach, należy zastosować konwersję przed znakami reprezentowanymi w pamięci zostaną przeniesione do przechowywania w plikach.
źródło
Miejmy prosty jednoznakowy ciąg
'š'
i zakodujemy go w sekwencji bajtów:Na potrzeby tego przykładu wyświetlmy sekwencję bajtów w postaci binarnej:
Teraz generalnie nie jest możliwe odkodowanie informacji bez wiedzy, w jaki sposób została zakodowana. Tylko jeśli wiesz, że zastosowano
utf-8
kodowanie tekstu, możesz postępować zgodnie z algorytmem dekodowania utf-8 i uzyskać oryginalny ciąg znaków:Możesz wyświetlić liczbę binarną z
101100001
powrotem jako ciąg:źródło
Języki Python obejmują
str
ibytes
jako standardowe „typy wbudowane”. Innymi słowy, obie są klasami. Nie sądzę, że warto próbować zracjonalizować, dlaczego Python został wdrożony w ten sposób.Mimo, że
str
ibytes
są bardzo podobne do siebie. Oba korzystają z większości tych samych metod. Następujące metody są unikalne dla tejstr
klasy:Następujące metody są unikalne dla tej
bytes
klasy:źródło