TypeError : un objet de type bytes est requis, pas 'str&#39 ; lors de l'écriture dans un fichier en Python3

J&#8217ai très récemment migré vers Py 3.5. Ce code fonctionnait correctement dans 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

Après la mise à niveau vers la version 3.5, j'obtiens le :

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

sur la dernière ligne (le code de recherche de motif).

J'ai essayé d'utiliser la fonction .decode() de part et d'autre de la déclaration, j'ai également essayé :

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

- sans succès.

J'ai pu résoudre rapidement presque tous les problèmes de 2:3, mais cette petite déclaration me dérange.

Solution

Vous avez ouvert le fichier en mode binaire :

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

Cela signifie que toutes les données lues dans le fichier sont retournées sous forme d'objets bytes et non str. Vous ne pouvez donc pas utiliser une chaîne de caractères dans un test de confinement :

if 'some-pattern' in tmp: continue

Vous devez utiliser un objet bytes pour tester le contenu de tmp :

if b'some-pattern' in tmp: continue

ou ouvrir le fichier comme un fichier texte en remplaçant le mode 'rb' par 'r'.

Commentaires (3)

Comme il a déjà été mentionné, vous lisez le fichier en mode binaire et créez ensuite une liste d'octets. Dans la boucle for suivante, vous comparez la chaîne aux octets et c'est là que le code échoue.

Décoder les octets tout en ajoutant à la liste devrait fonctionner. Le code modifié devrait ressembler à ceci :

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

Le type bytes a été introduit dans Python 3 et c'est pourquoi votre code fonctionnait dans Python 2. Dans Python 2, il n'y avait pas de type de données pour les octets :

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

pour ce petit exemple : 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()

en ajoutant le "b&quot ; devant 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n&#39 ; a résolu mon problème

Commentaires (0)