2017-11-13 3 views
1

Der folgende Code erklärt mein Problem. Es funktioniert wie erwartet in Python 2.7, aber alle Encoding-Aufrufe, die ich versucht habe, scheitern in Python 3.5 (siehe Ausnahme unten) ... ist jemand auf einem Weg, um diesen Fehler zu umgehen und es so in Python 3.5 arbeiten zu lassen auf Python 2.7?Wie konvertiert man in Python 3 chr (0xdfff) in utf-8 Bytes wie in Python 2?

import sys 

if sys.version_info[0] <= 2: 
    chr = unichr 

out = chr(0xdfff) 
print(repr(out)) # outputs '\udfff' both in Python 2 and 3 
assert out.encode('utf-8').decode('utf-8') == out 
assert out.encode('utf-8', errors='surrogateescape').decode('utf-8') == out 
assert out.encode('utf-8', errors='strict').decode('utf-8') == out 

Fehler in Python 3.5:

Traceback (most recent call last): 
    File "W:\rocky40\Projects\etk\coilib50\source\python\coilib50\io\xmlpickle\snippet.py", line 8, in <module> 
    assert out.encode('utf-8').decode('utf-8') == out 
UnicodeEncodeError: 'utf-8' codec can't encode character '\udfff' in position 0: surrogates not allowed 

Beachten Sie, dass eine andere Codierung wäre es nicht wirklich passen, wie ich Dateien auf diese Weise auf die Festplatte in Python geschrieben haben 2 und ich müssen in der Lage zu laden es zurück und dump es wieder auf Python 3, so dass Python 2 es wieder lesen kann (so sollten die tatsächlich geschriebenen Bytes nicht wirklich ändern).

+0

Warum sollten Sie erwarten, dass dies funktioniert? –

+0

@JoshLee, weil es auf Python 2 funktioniert;) –

Antwort

0

haben Nach etwas mehr suchen ich bemerkte, dass https://docs.python.org/3/library/codecs.html#codec-base-classes verweist auf eine surrogatepass, die zu utf-X Codecs spezifisch ist, so, mit surrogatepass statt surrogateescape scheint der Trick getan und funktioniert auf Python 3 zu erhalten:

assert out.encode('utf-8', errors='surrogatepass' 
    ).decode('utf-8', errors='surrogatepass') == out 
0

Das Problem ist, dass char auf UTF-16 gehört:

import sys 

if sys.version_info[0] <= 2: 
    chr = unichr 

out = chr(0xdfff) 

print(out.encode('utf-16-le', 'ignore').decode('utf-16-le', 'ignore') == out) 
print(out.encode('utf-16-le', 'ignore').decode('utf-16-le', 'ignore') == out) 
print(out.encode('utf-16-le', 'ignore').decode('utf-16-le', 'ignore') == out) 

Das und arbeitet kompiliert, aber ... Acording zu this answer, werden Sie Probleme mit Surrogaten

+0

Eigentlich habe ich einen besseren Weg gefunden mit 'surrogatepass' auf encode/decode: https://Stackoverflow.com/a/47283019/110451 –

Verwandte Themen