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)
Kode python di atas memberi saya kesalahan berikut:
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
Jawaban:
Jika Anda menggunakan Python3x maka
string
bukan jenis yang sama dengan Python 2.x, Anda harus membuangnya ke byte (menyandikannya).Juga tidak menggunakan nama variabel seperti
string
ataufile
sementara itu adalah nama modul atau fungsi.EDIT @Tom
Ya, teks non-ASCII juga dikompresi / didekompresi. Saya menggunakan huruf Polandia dengan pengkodean UTF-8:
sumber
str
) dan kembali tidak diperlukan, dan berisiko kesalahan penguraian atau ketidaksesuaian antara input dan output.Ada solusi yang lebih mudah untuk masalah ini.
Anda hanya perlu menambahkan
t
ke mode sehingga menjadiwt
. Ini menyebabkan Python untuk membuka file sebagai file teks dan bukan biner. Maka semuanya akan bekerja.Program lengkap menjadi ini:
sumber
Anda tidak dapat membuat serial 'string' Python ke byte tanpa menjelaskan konversi ke beberapa pengkodean.
mungkin apa yang Anda inginkan. Ini juga berfungsi untuk kedua python 2.x dan 3.x.
sumber
Untuk Python 3.x Anda dapat mengubah teks Anda menjadi byte mentah melalui:
Sebagai contoh:
Objek yang dikembalikan akan bekerja dengannya
outfile.write
.sumber
Masalah ini umumnya terjadi ketika beralih dari py2 ke py3. Dalam py2
plaintext
adalah tipe string dan byte byte . Dalam py3plaintext
hanya sebuah string , dan metode inioutfile.write()
benar-benar mengambil array byte saatoutfile
dibuka dalam mode biner, jadi pengecualian dimunculkan. Ubah input keplaintext.encode('utf-8')
untuk memperbaiki masalah. Baca terus jika ini mengganggu Anda.Dalam py2, yang deklarasi file.write membuatnya tampak seperti Anda melewati dalam sebuah string:
file.write(str)
. Sebenarnya Anda lewat di array byte, Anda seharusnya membaca deklarasi seperti ini:file.write(bytes)
. Jika Anda membacanya seperti ini masalahnya sederhana,file.write(bytes)
perlu tipe byte dan di py3 untuk mendapatkan byte dari str Anda mengubahnya:Mengapa dokumen py2 menyatakan
file.write
mengambil string? Nah di py2 perbedaan deklarasi tidak masalah karena:Kelas str-bytes py2 memiliki metode / konstruktor yang membuatnya berperilaku seperti kelas string dalam beberapa hal dan kelas array byte di orang lain. Nyaman
file.write
bukan ?:Mengapa py3 merusak sistem yang bagus ini? Nah karena dalam fungsi string dasar py2 tidak bekerja untuk seluruh dunia. Mengukur panjang kata dengan karakter non-ASCII?
Selama ini Anda mengira Anda meminta len dari string di py2, Anda mendapatkan panjang byte array dari pengkodean. Ambiguitas itu adalah masalah mendasar dengan kelas tugas ganda. Versi panggilan metode apa saja yang Anda terapkan?
Kabar baiknya adalah bahwa py3 memperbaiki masalah ini. Ini menguraikan kelas str dan byte . Kelas str memiliki metode seperti string, kelas byte yang terpisah memiliki metode array byte:
Semoga mengetahui hal ini membantu menghilangkan misteri masalah, dan membuat rasa sakit migrasi sedikit lebih mudah untuk ditanggung.
sumber
Nah, jika berguna untuk Anda jika Anda menghilangkan karakter 'b' yang mengganggu.
sumber
s.encode('utf-8')
sangat pythonic sebagais.decode('utf-8')
penggantis = bytes("s", "utf-8")
Untuk
Django
dalamdjango.test.TestCase
pengujian unit, saya mengubah sintaks Python2 saya :Untuk menggunakan sintaks Python3
.decode('utf8')
:sumber