2017-01-22 29 views
2

Ich habe ein rudimentäres Verständnis von Python, bin aber nicht klar im Umgang mit Binärcodierungsprobleme. Ich versuche, Beispielcode von einem firefox-webextensions-Beispiel auszuführen, in dem ein Python-Skript Text sendet, der von einem Javascript-Programm gelesen wird. Ich stoße immer wieder auf Codierungsfehler.Codierung: TypeError: Write() Argument muss Str sein, nicht Bytes

Der Python-Code ist:

#! /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 
import sys, json, struct 

text = "pong" 

encodedContent = json.dumps(text) 
encodedLength = struct.pack('@I', len(encodedContent)) 
encodedMessage = {'length': encodedLength, 'content': encodedContent} 

sys.stdout.write(encodedMessage['length']) 
sys.stdout.write(encodedMessage['content']) 

Der Fehler trace (in Firefox Konsole angezeigt) ist:

stderr output from native app chatX: Traceback (most recent call last): 
stderr output from native app chatX: File "/Users/inchem/Documents/firefox addons/py/chatX.py", line 10, in <module> 
stderr output from native app chatX: sys.stdout.write(encodedMessage['length']) 
stderr output from native app chatX: TypeError: write() argument must be str, not bytes 

Lauf Python 3.5.1 auf OS X El Capitan 10.11.6, x86 64-Bit Zentralprozessor; firefox Entwickler ed 52,0

Der Python-Skript, die ich benutze, wie oben gezeigt, von den ursprünglichen bei https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Native_messaging

ich auch versucht, minimiert wird:

sys.stdout.buffer.write(encodedMessage['length']) 
sys.stdout.buffer.write(encodedMessage['content']) 

, die erzeugt:

stderr output from native app chatX: sys.stdout.buffer.write(encodedMessage['content']) 
stderr output from native app chatX: TypeError: a bytes-like object is required, not 'str'  
+0

haben Sie es zu Zeichenfolge wie folgt aus? Sys.stdout.buffer.write (str (encodedMessage [ 'Länge'] zu konvertieren versucht)) – Shiping

Antwort

3

Das Beispiel war wahrscheinlich Python 2-konform, aber die Dinge haben sich in Python 3 geändert.

Sie eine binäre Darstellung der Länge als Bytes mit diesem zu erzeugen:

encodedLength = struct.pack('@I', len(encodedContent)) 

Es ist nicht druckbar ist. Sie können es über einen Socket-Stream schreiben, der ein binärer Stream ist, aber nicht durch stdout, der ein Text-Stream ist.

Der Trick buffer der (wie in How to write binary data in stdout in python 3? erklärt) gut ist, aber nur für den binären Teil (beachten Sie, dass Sie die Fehlermeldung für den Textteil jetzt erhalten):

sys.stdout.buffer.write(encodedMessage['length']) 

Für den Textteil, schreiben Sie einfach an stdout:

sys.stdout.write(encodedMessage['content']) 

oder verwenden sys.stdout.buffer mit String-Bytes-Konvertierung:

sys.stdout.buffer.write(bytes(encodedMessage['content'],"utf-8")) 
0

Sie müssen sicherstellen, dass Ihre Eingabe Str (Unicode) vor dem Schreiben in stdout/stderr ist.

in Ihrem Beispiel:

sys.stdout.write(encodedMessage['length'].decode('utf8')) 
sys.stdout.write(encodedMessage['content']) 

können Sie sehen, dass type(encodedLength))bytes während type(encodedContent) ist str.

bitte the following answer für weitere Informationen über Bytes vs String in python3.X lesen

+0

Sehr hilfreich. Vielen Dank. –

Verwandte Themen