"TypeError: se requiere un objeto similar a bytes, no 'str'" al manejar el contenido del archivo en Python 3

Resuelto masroore asked hace 8 años • 11 respuestas

Recientemente migré a Python 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

Pero en 3.5, en la if 'some-pattern' in tmp: continuelínea, aparece un error que dice:

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

No pude solucionar el problema usando .decode()ninguno de los lados de in, ni pude solucionarlo usando

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

¿Qué está mal y cómo lo soluciono?

masroore avatar Oct 10 '15 20:10 masroore
Aceptado

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 bytesobjetos, no como archivos str. Entonces no puedes usar una cadena en una prueba de contención:

if 'some-pattern' in tmp: continue

En su lugar , tendrías que usar un bytesobjeto para probar tmp:

if b'some-pattern' in tmp: continue

o abra el archivo como un archivo de texto reemplazando el 'rb'modo con 'r'.

Martijn Pieters avatar Oct 10 '2015 13:10 Martijn Pieters

Puedes codificar tu cadena usando.encode()

Ejemplo:

'Hello World'.encode()

Como describe el error, para escribir una cadena en un archivo, primero debe codificarla en un objeto similar a un byte, y encode()codificarla en una cadena de bytes.

Theofilos Papapanagiotou avatar May 22 '2016 16:05 Theofilos Papapanagiotou

Como ya se mencionó, está leyendo el archivo en modo binario y luego creando una lista de bytes. En el siguiente bucle for , está comparando cadenas con bytes y ahí es donde falla el código.

Decodificar los bytes mientras se agregan a la lista debería funcionar. El código modificado debería verse de la siguiente manera:

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

El tipo 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)
<type 'str'>
Suresh avatar May 17 '2016 02:05 Suresh

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 puedes escribir en el archivo (en mi caso). ¿Entonces después de todo no tengo una respuesta?

Fuente: Cómo eliminar ^M

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

meck373 avatar Apr 28 '2017 14:04 meck373

Para este pequeño ejemplo, agregar el único banterior 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n'resolvió mi problema:

import 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()

¿Qué hace el carácter 'b' delante de una cadena literal?

starter avatar Mar 22 '2016 11:03 starter