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

Después de actualizar a 3.5, obtengo:

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

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

Intenté usar la .decode()función en cualquier lado de la declaración y también probé:

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

- en vano.

Pude resolver casi todos los problemas de Python 2 a Python 3 rápidamente, pero esta pequeña declaración me estaba molestando.

respuesta

Abrió 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 puede usar una cadena en una prueba de contención:

if 'some-pattern' in tmp: continue

Tendrías que usar un bytesobjeto para probar en tmpsu lugar:

if b'some-pattern' in tmp: continue

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

Puede codificar su cadena usando.encode()

Ejemplo:

'Hello World'.encode()

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

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

La decodificación de los bytes mientras se agrega a la lista debería funcionar. El código modificado debería tener el siguiente aspecto:

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)
<type 'str'>

Tienes que cambiar de wb a w:

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

para

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

Para este pequeño ejemplo, agregar la "b" antes de '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()

Utilice la función encode() junto con el valor de cadena codificado de forma rígida que se proporciona entre comillas simples.

Ejemplo:

file.write(answers[i] + '\n'.encode())

O

line.split(' +++$+++ '.encode())

Abrió el archivo en modo binario:

El siguiente código arrojará un TypeError: se requiere un objeto similar a bytes, no 'str'.

for line in lines:
    print(type(line))# <class 'bytes'>
    if 'substring' in line:
       print('success')

El siguiente código funcionará; debe usar la función decode ():

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

Intente 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: io — Herramientas principales para trabajar con flujos .

Y esta es la función abierta: abrir

Si realmente está tratando de manejarlo como un binario, considere codificar su cadena.

Recibí este error cuando intentaba convertir un carácter (o cadena) a bytes, el código era algo así con Python 2.7:

# -*- coding: utf-8 -*-
print(bytes('ò'))

Esta es la forma de Python 2.7 cuando se trata de caracteres Unicode.

Esto no funcionará con Python 3.6, ya bytesque requiere un argumento adicional para la codificación, pero esto puede ser un poco complicado, ya que una codificación diferente puede generar resultados diferentes:

print(bytes('ò', 'iso_8859_1')) # prints: b'\xf2'
print(bytes('ò', 'utf-8')) # prints: b'\xc3\xb2'

En mi caso, tuve que usar iso_8859_1al codificar bytes para resolver el problema.