2012-12-23 11 views
59

To jest pytanie typu Pythona 101, ale przez chwilę miałem kłopot, gdy próbowałem użyć pakietu, który wydawał się konwertować moje dane wejściowe do bajtów.Jak przekonwertować bajty i łańcuchy w Pythonie 3?

Jak zobaczycie poniżej, znalazłem odpowiedź dla siebie, ale czułem, że warto tu nagrywać, ponieważ czas zajęło mi odkrycie tego, co się dzieje. Wydaje się, że jest on generyczny dla Pythona 3, więc nie odniosłem się do oryginalnego pakietu, w którym grałem; nie wydaje się być błąd (wystarczy, że dany pakiet miał .tostring() metodę, która była wyraźnie nie produkujący co zrozumiałem jako ciąg ...)

Mój program testowy idzie tak:

import mangler         # spoof package 

stringThing = """ 
<Doc> 
    <Greeting>Hello World</Greeting> 
    <Greeting>你好</Greeting> 
</Doc> 
""" 

# print out the input 
print('This is the string input:') 
print(stringThing) 

# now make the string into bytes 
bytesThing = mangler.tostring(stringThing) # pseudo-code again 

# now print it out 
print('\nThis is the bytes output:') 
print(bytesThing) 

wyjście z tego kodu daje to:

This is the string input: 

<Doc> 
    <Greeting>Hello World</Greeting> 
    <Greeting>你好</Greeting> 
</Doc> 


This is the bytes output: 
b'\n<Doc>\n <Greeting>Hello World</Greeting>\n <Greeting>\xe4\xbd\xa0\xe5\xa5\xbd</Greeting>\n</Doc>\n' 

Tak, istnieje potrzeba, aby móc konwertować między bajtów i ciągi, aby uniknąć kończąc znaki spoza ASCII zamienia się bełkot.

+1

[Pytanie] (http://stackoverflow.com/questions/7585435/best-way-to-convert-string-to-bytes-in-python-3) daje więcej szczegółów w odpowiedzi, ale myślę, że krótsza odpowiedź poniżej jest bardziej jasna. – Bobble

Odpowiedz

89

do „mangler” w powyższym przykładzie kodu robi równowartość to:

bytesThing = stringThing.encode(encoding='UTF-8') 

Istnieją inne sposoby, aby napisać to (zwłaszcza przy użyciu bytes(stringThing, encoding='UTF-8'), ale powyżej składnia sprawia, że ​​oczywiste, co się dzieje , a także co zrobić, aby odzyskać ciąg.

newStringThing = bytesThing.decode(encoding='UTF-8') 

Kiedy to zrobimy, oryginalny łańcuch są odzyskiwane

Uwaga, używając str(bytesThing) właśnie transkrybuje wszystkie żałobne fragmenty bez konwersji z powrotem do Unicode, chyba że konkretnie zażądasz UTF-8, mianowicie., str(bytesThing, encoding='UTF-8'). Nie zgłoszono błędu, jeśli kodowanie nie zostało określone.

+0

Jeśli spojrzysz na rzeczywiste implementacje metod, zobaczysz, że 'utf-8' jest domyślnym kodowaniem, dlatego możesz go pominąć, ponieważ wiesz, że kodowanie jest w rzeczywistości' utf-8', tj. 'StringThing.encode () 'i' bytesThing.decode() 'będzie dobrze. – ccpizza

+0

@ccpizza Dokonywanie kodowania jawnie w powyższych przykładach sprawia, że ​​o wiele jaśniejsze jest to, co się dzieje, a IMHO jest dobrą praktyką. Nie wszystkie kody Unicode to UTF-8. Pozwala to również uniknąć cichej awarii, o której mowa w ostatnim akapicie. – Bobble

+0

całkowicie zgadzam się; explicite jest lepsze niż niejawne, ale imo dobrze jest wiedzieć, co ** jest ** niejawne. To, czy go użyć czy nie, to kolejne pytanie. Tylko dlatego, że nie oznacza to, że powinieneś :) – ccpizza

11

W python3 istnieje metoda bytes() w tym samym formacie co encode().

str1 = b'hello world' 
str2 = bytes("hello world", encoding="UTF-8") 
print(str1 == str2) # Returns True 

Nic nie czytałem w dokumentach, ale może nie szukałem we właściwym miejscu. W ten sposób można jawnie przekształcić ciągi w strumienie bajtów i zapewnić ich większą czytelność niż przy użyciu encode i decode i bez konieczności poprzedzania cytowaniem przedrostka b.

1

TRY TO:

StringVariable=ByteVariable.decode('UTF-8','ignore') 

DO Badanie typu:

print(type(StringVariable)) 

Oto StringVariable 'reprezentowany jako ciąg znaków. "ByteVariable" oznacza Byte. Nie jest dowiemy się z zakwestionować zmiennych ..

Powiązane problemy