Dieses Problem tritt häufig beim Wechsel von py2 zu py3 auf. In PY2 plaintext
ist sowohl eine Zeichenkette und ein Byte - Array - Typ. In py3 plaintext
ist nur eine Zeichenfolge vorhanden , und die Methode outfile.write()
benötigt beim Öffnen im Binärmodus tatsächlich ein Byte-Arrayoutfile
, sodass eine Ausnahme ausgelöst wird . Ändern Sie die Eingabe in plaintext.encode('utf-8')
, um das Problem zu beheben. Lesen Sie weiter, wenn Sie dies stört.
In py2 hat die Deklaration für file.write den Anschein erweckt , als hätten Sie eine Zeichenfolge übergeben : file.write(str)
. Eigentlich haben Sie ein Byte-Array übergeben, Sie sollten die Deklaration wie folgt gelesen haben : file.write(bytes)
. Wenn Sie es so das Problem ist einfach zu lesen, file.write(bytes)
muss ein Byte - Typ und in py3 bekommen Bytes aus einem str Sie es konvertieren:
py3>> outfile.write(plaintext.encode('utf-8'))
Warum haben die py2-Dokumente angegeben, dass file.write
eine Zeichenfolge verwendet wurde? Nun, in py2 war die Deklarationsunterscheidung nicht wichtig, weil:
py2>> str==bytes #str and bytes aliased a single hybrid class in py2
True
Die str-bytes- Klasse von py2 verfügt über Methoden / Konstruktoren, mit denen sie sich in gewisser Weise wie eine String-Klasse und in anderen wie eine Byte-Array-Klasse verhält. Praktisch für file.write
nicht wahr?:
py2>> plaintext='my string literal'
py2>> type(plaintext)
str #is it a string or is it a byte array? it's both!
py2>> outfile.write(plaintext) #can use plaintext as a byte array
Warum hat py3 dieses schöne System kaputt gemacht? Nun, weil in py2 grundlegende String-Funktionen für den Rest der Welt nicht funktionierten. Die Länge eines Wortes mit einem Nicht-ASCII-Zeichen messen?
py2>> len('¡no') #length of string=3, length of UTF-8 byte array=4, since with variable len encoding the non-ASCII chars = 2-6 bytes
4 #always gives bytes.len not str.len
Die ganze Zeit über Sie dachten , Sie wurden für die fragen len einer Zeichenkette in py2, Sie waren immer die Länge des Byte - Array von der Codierung. Diese Mehrdeutigkeit ist das grundlegende Problem bei Klassen mit doppelter Pflicht. Welche Version eines Methodenaufrufs implementieren Sie?
Die gute Nachricht ist dann, dass py3 dieses Problem behebt. Es entwirrt die Klassen str und bytes . Die str- Klasse verfügt über stringähnliche Methoden, die separate Byteklasse über Byte-Array-Methoden:
py3>> len('¡ok') #string
3
py3>> len('¡ok'.encode('utf-8')) #bytes
4
Hoffentlich hilft es, das Problem zu enträtseln und den Migrationsschmerz ein wenig leichter zu ertragen.