builtins.TypeError: musi być ciągiem, a nie bajtami

220

Przekształciłem swoje skrypty z Python 2.7 na 3.2 i mam błąd.

# -*- 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) 

W ostatnim wierszu dostałem ten błąd:

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)

Zainstalowałem Python 3.2 i zainstalowałem lxml-2.3.win32-py3.2.exe.

W Pythonie 2.7 działa.

użytkownik278618
źródło
10
Naprawdę nie zbadałem tego, ale szybko zgaduję, że powinieneś otworzyć plik w trybie binarnym.
Sven Marnach

Odpowiedzi:

484

Plik wyjściowy powinien być w trybie binarnym.

outFile = open('output.xml', 'wb')
Lennart Regebro
źródło
100
Umysł oszalał. Python3 przeprojektował, co zrobić z tym małym „b”. Kiedyś denerwowało tylko użytkowników systemu Windows, którzy zapomnieli go dołączyć (lub nie mogli tego zrobić, ponieważ używali standardowego interfejsu). Teraz może denerwować użytkowników Pythona na wszystkich platformach. Mam nadzieję, że będzie to warte bólu.
nobar
5
Jeśli parsujesz tekst, zdecydowanie warto.
Lennart Regebro
@nobar Wymagane jest np. wyłączenie Uniwersalnej obsługi nowej linii, legacy.python.org/dev/peps/pep-0278 , która jest domyślnie włączona w Pythonie 3
użytkownik7610
Działa dla mnie również w gzip dla python3! json.load(gzip.open('file.json.gz'))nie json.load(gzip.open('file.json.gz', 'rt'))udaje się i udaje!
płyty grzewcze
@ LennartRegebro, Nie, jeśli ustawienie systemowe jest nieoczekiwane. Binarny jest najlepszy i mniej podatny na błędy. Jeśli to działa, to naprawdę działa. W przypadku tekstu zawsze występuje „co jeśli”.
Pacerier
6

Konwertuj plik binarny na base64 i odwrotnie. Udowodnij w 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
źródło