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)
Le code python ci-dessus me donne l'erreur suivante:
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
Réponses:
Si vous utilisez Python3x alors qu'il
string
n'est pas du même type que pour Python 2.x, vous devez le convertir en octets (le coder).N'utilisez pas non plus de noms de variables comme
string
oufile
alors que ce sont des noms de module ou de fonction.EDIT @Tom
Oui, le texte non ASCII est également compressé / décompressé. J'utilise des lettres polonaises avec un encodage UTF-8:
la source
str
) et inversement n'est pas nécessaire et risque de provoquer des erreurs de décodage ou des décalages entre l'entrée et la sortie.Il existe une solution plus simple à ce problème.
Vous avez juste besoin d'ajouter un
t
au mode pour qu'il deviennewt
. Cela provoque Python pour ouvrir le fichier en tant que fichier texte et non binaire. Ensuite, tout fonctionnera.Le programme complet devient ceci:
la source
Vous ne pouvez pas sérialiser une 'chaîne' Python 3 en octets sans expliquer la conversion en un certain encodage.
est peut-être ce que vous voulez. Cela fonctionne également pour python 2.x et 3.x.
la source
Pour Python 3.x, vous pouvez convertir votre texte en octets bruts via:
Par exemple:
L'objet retourné fonctionnera avec
outfile.write
.la source
Ce problème se produit généralement lors du passage de py2 à py3. Dans py2
plaintext
est à la fois une chaîne et un type de tableau d'octets . Dans py3plaintext
est seulement une chaîne , et la méthodeoutfile.write()
prend en fait un tableau d'octets lorsqu'elleoutfile
est ouverte en mode binaire, donc une exception est levée. Modifiez l'entréeplaintext.encode('utf-8')
pour résoudre le problème. Continuez à lire si cela vous dérange.En py2, la déclaration de file.write fait croire que vous avez passé dans une chaîne:
file.write(str)
. En fait , vous étiez de passage dans un tableau d'octets, vous devriez avoir été lu la déclaration comme ceci:file.write(bytes)
. Si vous le lisez comme ceci, le problème est simple, afile.write(bytes)
besoin d'un type d' octets et dans py3 pour obtenir des octets d'une chaîne, vous le convertissez:Pourquoi les documents py2 ont-ils déclaré avoir
file.write
pris une chaîne? Eh bien dans py2, la distinction de déclaration n'a pas d'importance car:La classe str-bytes de py2 a des méthodes / constructeurs qui la font se comporter comme une classe de chaîne à certains égards et une classe de tableau d'octets à d'autres. Pratique pour
file.write
non?:Pourquoi py3 a-t-il cassé ce joli système? Eh bien parce que dans py2, les fonctions de chaîne de base ne fonctionnaient pas pour le reste du monde. Mesurer la longueur d'un mot avec un caractère non ASCII?
Pendant tout ce temps que vous pensiez que vous demandiez l' len d'une chaîne dans py2, vous receviez la longueur du tableau d'octets du codage. Cette ambiguïté est le problème fondamental des classes à double droit. Quelle version d'un appel de méthode implémentez-vous?
La bonne nouvelle est que py3 résout ce problème. Il démêle les classes str et bytes . La classe str a des méthodes de type chaîne, la classe d' octets séparée a des méthodes de tableau d'octets:
Espérons que le savoir aide à démystifier le problème et rend la douleur migratoire un peu plus facile à supporter.
la source
Eh bien, si cela vous est utile en cas de suppression du caractère `` b '' gênant.Si quelqu'un a une meilleure idée, veuillez me suggérer ou n'hésitez pas à me modifier à tout moment ici.Je suis juste un débutant
la source
s.encode('utf-8')
si pythonique qu'ens.decode('utf-8')
remplacement des = bytes("s", "utf-8")
Pour
Django
endjango.test.TestCase
tests unitaires, j'ai changé python2 syntaxe:Pour utiliser la syntaxe Python3
.decode('utf8')
:la source