TypeError: se requiere un objeto de tipo bytes, no ‘str’ al escribir en un archivo en Python3

Recientemente he migrado a Py 3.5. Este código funcionaba correctamente en Python 2.7:

with open(fname, 'rb') as f: lines = [x.strip() for x in f.readlines()] for line in lines: tmp = line.strip().lower() if 'some-pattern' in tmp: continue # ... code 

Después de actualizar a 3.5, recibo el:

 TypeError: a bytes-like object is required, not 'str' 

error en la última línea (el código de búsqueda de patrón).

He intentado usar la función .decode() en cualquiera de los lados de la statement, también probé:

 if tmp.find('some-pattern') != -1: continue 

– en vano.

Pude resolver casi todos los problemas 2: 3 rápidamente, pero esta pequeña statement me está molestando.

Abriste el archivo en modo binario:

 with open(fname, 'rb') as f: 

Esto significa que todos los datos leídos del archivo se devuelven como objetos de bytes , no como str . No puedes usar una cadena en una prueba de contención:

 if 'some-pattern' in tmp: continue 

Tendrías que usar un objeto de bytes para probar contra tmp lugar:

 if b'some-pattern' in tmp: continue 

o abra el archivo como un archivo de texto sustituyendo el modo 'rb' por 'r' .

Puedes codificar tu cadena usando .encode()

Ejemplo:

 'Hello World'.encode() 

Como ya se ha mencionado, está leyendo el archivo en modo binario y luego creando una lista de bytes. En el siguiente bucle para el bucle, está comparando la cadena con los bytes y ahí es donde el código está fallando.

Decodificar los bytes mientras se agrega a la lista debería funcionar. El código modificado debe verse como sigue:

 with open(fname, 'rb') as f: lines = [x.decode('utf8').strip() for x in f.readlines()] 

El tipo de bytes se introdujo en Python 3 y es por eso que su código funcionó en Python 2. En Python 2 no había ningún tipo de datos para bytes:

 >>> s=bytes('hello') >>> type(s)  

para este pequeño ejemplo: importar socket

 mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mysock.connect(('www.py4inf.com', 80)) mysock.send(**b**'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n') while True: data = mysock.recv(512) if ( len(data) < 1 ) : break print (data); mysock.close() 

agregar la "b" antes de 'GET http://www.py4inf.com/code/romeo.txt HTTP / 1.0 \ n \ n' solucionó mi problema

Tienes que cambiar de wb a w:

 def __init__(self): self.myCsv = csv.writer(open('Item.csv', 'wb')) self.myCsv.writerow(['title', 'link']) 

a

 def __init__(self): self.myCsv = csv.writer(open('Item.csv', 'w')) self.myCsv.writerow(['title', 'link']) 

Después de cambiar esto, el error desaparece, pero no puede escribir en el archivo (en mi caso). Así que después de todo, no tengo una respuesta?

Fuente: Cómo eliminar ^ M

Cambiar a ‘rb’ me trae el otro error: io.UnsupportedOperation: write

¿Por qué no intenta abrir su archivo como texto?

 with open(fname, 'rt') as f: lines = [x.strip() for x in f.readlines()] 

Además, aquí hay un enlace para Python 3.x en la página oficial: https://docs.python.org/3/library/io.html Y esta es la función abierta: https://docs.python.org/3 /library/functions.html#open

Si realmente estás tratando de manejarlo como un binario, entonces considera codificar tu cadena.

Abriste el archivo en modo binario:

El siguiente código lanzará un TypeError: se requiere un objeto de tipo bytes, no ‘str’.

 for line in lines: print(type(line))#  if 'substring' in line: print('success') 

El siguiente código funcionará: tienes que usar la función decode ():

 for line in lines: line = line.decode() print(type(line))#  if 'substring' in line: print('success')