builtins.TypeError: doit être str, pas d'octets

220

J'ai converti mes scripts de Python 2.7 en 3.2 et j'ai un bug.

# -*- coding: utf-8 -*-
import time
from datetime import date
from lxml import etree
from collections import OrderedDict

# Create the root element
page = etree.Element('results')

# Make a new document tree
doc = etree.ElementTree(page)

# Add the subelements
pageElement = etree.SubElement(page, 'Country',Tim = 'Now', 
                                      name='Germany', AnotherParameter = 'Bye',
                                      Code='DE',
                                      Storage='Basic')
pageElement = etree.SubElement(page, 'City', 
                                      name='Germany',
                                      Code='PZ',
                                      Storage='Basic',AnotherParameter = 'Hello')
# For multiple multiple attributes, use as shown above

# Save to XML file
outFile = open('output.xml', 'w')
doc.write(outFile) 

Sur la dernière ligne, j'ai eu cette erreur:

builtins.TypeError: must be str, not bytes
File "C:\PythonExamples\XmlReportGeneratorExample.py", line 29, in <module>
  doc.write(outFile)
File "c:\Python32\Lib\site-packages\lxml\etree.pyd", line 1853, in lxml.etree._ElementTree.write (src/lxml/lxml.etree.c:44355)
File "c:\Python32\Lib\site-packages\lxml\etree.pyd", line 478, in lxml.etree._tofilelike (src/lxml/lxml.etree.c:90649)
File "c:\Python32\Lib\site-packages\lxml\etree.pyd", line 282, in lxml.etree._ExceptionContext._raise_if_stored (src/lxml/lxml.etree.c:7972)
File "c:\Python32\Lib\site-packages\lxml\etree.pyd", line 378, in lxml.etree._FilelikeWriter.write (src/lxml/lxml.etree.c:89527)

J'ai installé Python 3.2 et j'ai installé lxml-2.3.win32-py3.2.exe.

Sur Python 2.7, cela fonctionne.

user278618
la source
10
N'a pas vraiment étudié cela, mais une supposition rapide est que vous devez ouvrir le fichier en mode binaire.
Sven Marnach

Réponses:

484

Le fichier de sortie doit être en mode binaire.

outFile = open('output.xml', 'wb')
Lennart Regebro
la source
100
L'esprit soufflé. Python3 a repensé quoi faire avec ce petit «b». Il agaçait uniquement les utilisateurs de Windows qui oubliaient de l'inclure (ou ne pouvaient pas parce qu'ils utilisaient stdio). Maintenant, il peut agacer les utilisateurs de Python sur toutes les plateformes. Espérons que cela en vaudra la peine.
nobar
5
Si vous analysez du texte, cela en vaut vraiment la peine.
Lennart Regebro
@nobar Il est nécessaire par exemple de désactiver la prise en charge de la nouvelle ligne universelle, legacy.python.org/dev/peps/pep-0278 , qui est activée par défaut dans Python 3
user7610
Fonctionne pour moi dans gzip pour python3 aussi! json.load(gzip.open('file.json.gz'))échoue et json.load(gzip.open('file.json.gz', 'rt'))réussit!
plaques de cuisson
@LennartRegebro, pas si le paramètre système est inattendu. Le binaire est meilleur et moins sujet aux erreurs. Si cela fonctionne, cela fonctionne vraiment. Quant au texte, il y a toujours un «et si».
Pacerier
6

Convertissez le fichier binaire en base64 et vice versa. Prouver en python 3.5.2

import base64

read_file = open('/tmp/newgalax.png', 'rb')
data = read_file.read()

b64 = base64.b64encode(data)

print (b64)

# Save file
decode_b64 = base64.b64decode(b64)
out_file = open('/tmp/out_newgalax.png', 'wb')
out_file.write(decode_b64)

# Test in python 3.5.2
djperalta
la source