plaintext = input("Please enter the text you want to compress")
filename = input("Please enter the desired filename")
with gzip.open(filename + ".gz", "wb") as outfile:
outfile.write(plaintext)
Der obige Python-Code gibt mir folgenden Fehler:
Traceback (most recent call last):
File "C:/Users/Ankur Gupta/Desktop/Python_works/gzip_work1.py", line 33, in <module>
compress_string()
File "C:/Users/Ankur Gupta/Desktop/Python_works/gzip_work1.py", line 15, in compress_string
outfile.write(plaintext)
File "C:\Python32\lib\gzip.py", line 312, in write
self.crc = zlib.crc32(data, self.crc) & 0xffffffff
TypeError: 'str' does not support the buffer interface
Antworten:
Wenn Sie Python3x verwenden,
string
ist dies nicht derselbe Typ wie für Python 2.x. Sie müssen es in Bytes umwandeln (codieren).Verwenden Sie auch keine Variablennamen wie
string
oderfile
während dies Namen von Modulen oder Funktionen sind.EDIT @Tom
Ja, Nicht-ASCII-Text wird ebenfalls komprimiert / dekomprimiert. Ich verwende polnische Buchstaben mit UTF-8-Codierung:
quelle
str
) und zurück ist nicht erforderlich und birgt das Risiko, dass Fehler oder Fehlanpassungen zwischen Eingabe und Ausgabe dekodiert werden.Es gibt eine einfachere Lösung für dieses Problem.
Sie müssen nur ein
t
zum Modus hinzufügen , damit es wirdwt
. Dies führt dazu, dass Python die Datei als Textdatei und nicht als Binärdatei öffnet. Dann wird einfach alles funktionieren.Das komplette Programm lautet wie folgt:
quelle
Sie können eine Python 3-Zeichenfolge nicht in Bytes serialisieren, ohne die Konvertierung in eine bestimmte Codierung zu erläutern.
ist möglicherweise was du willst. Dies funktioniert auch für Python 2.x und 3.x.
quelle
Für Python 3.x können Sie Ihren Text in Rohbytes konvertieren durch:
Beispielsweise:
Das zurückgegebene Objekt funktioniert mit
outfile.write
.quelle
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 py3plaintext
ist nur eine Zeichenfolge vorhanden , und die Methodeoutfile.write()
benötigt beim Öffnen im Binärmodus tatsächlich ein Byte-Arrayoutfile
, sodass eine Ausnahme ausgelöst wird . Ändern Sie die Eingabe inplaintext.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:Warum haben die py2-Dokumente angegeben, dass
file.write
eine Zeichenfolge verwendet wurde? Nun, in py2 war die Deklarationsunterscheidung nicht wichtig, weil: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?: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?
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:
Hoffentlich hilft es, das Problem zu enträtseln und den Migrationsschmerz ein wenig leichter zu ertragen.
quelle
Wenn jemand eine bessere Idee hat, schlagen Sie mich bitte vor oder bearbeiten Sie mich jederzeit hier. Ich bin nur ein Neuling
quelle
s.encode('utf-8')
es auch so pythonisch verwenden wie alss.decode('utf-8')
Ersatz fürs = bytes("s", "utf-8")
Für
Django
indjango.test.TestCase
Unit - Tests, änderte ich meine Python2 Syntax:So verwenden Sie die Python3-
.decode('utf8')
Syntax:quelle