python 3.5: TypeError: un objet de type bytes est requis, Pas 'str' lors de l'écriture dans un fichier

j'ai très récemment migré vers Py 3.5. Ce code fonctionnait correctement 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

après la mise à niveau à 3.5, je reçois le:

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

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

j'ai essayé d'utiliser la fonction .decode() de chaque côté de la déclaration, également essayé:

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

- en vain.

j'ai pu résoudre presque tous les numéros 2:3 sortent rapidement, mais cette petite déclaration me dérange.

291
demandé sur Martijn Pieters 2015-10-10 16:28:09

7 réponses

vous avez ouvert le fichier en mode binaire:

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

cela signifie que toutes les données lues à partir du fichier sont retournées comme bytes objets, pas str . Vous ne pouvez pas alors utiliser une chaîne dans un test de confinement:

if 'some-pattern' in tmp: continue

vous devez utiliser un bytes objet pour tester contre tmp à la place:

if b'some-pattern' in tmp: continue

ou ouvrez le fichier sous forme de fichier texte en remplaçant le mode 'rb' par 'r' .

295
répondu Martijn Pieters 2015-10-10 13:30:57

vous pouvez encoder votre chaîne en utilisant .encode()

exemple:

'Hello World'.encode()
70
répondu theofpa 2017-12-29 12:16:48

comme il a déjà été mentionné, vous êtes en train de lire le fichier en mode binaire, puis de créer une liste d'octets. Dans votre boucle suivante pour , 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 être le suivant:

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

le type d'octets a été introduit en Python 3 et c'est pourquoi votre code a fonctionné en Python 2. En Python 2, Il n'y avait pas de type de données pour les octets:

>>> s=bytes('hello')
>>> type(s)
<type 'str'>
23
répondu Suresh 2016-05-17 02:15:36

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

ajouter le" b " avant "GET http://www.py4inf.com/code/romeo.txt HTTP / 1.0\n\n' résolu mon problème

9
répondu starter 2016-03-22 11:59:17

vous devez passer de wb à w:

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

à

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

Après avoir changé cela, l'erreur disparaît, mais vous ne pouvez pas écrire dans le fichier (dans mon cas). Alors, après tout, je n'ai pas de réponse?

Source: comment supprimer ^m

changer en " rb " m'apporte l'autre erreur: io.Opération non supportée: écrire

4
répondu meck373 2017-05-23 12:26:27

pourquoi ne pas essayer d'ouvrir votre fichier sous forme de texte?

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

en outre, voici un lien pour python 3.x sur la page officielle: https://docs.python.org/3/library/io.html Et voici la fonction ouverte: https://docs.python.org/3/library/functions.html#open

si vous essayez vraiment de le gérer en tant que binaire, alors envisagez d'encoder votre chaîne.

2
répondu Fernando D Jaime 2017-12-01 12:35:30

vous avez ouvert le fichier en mode binaire:

le code suivant lancera une typographe: un objet de type bytes est requis, pas'str'.

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

le code suivant fonctionnera - vous devez utiliser la fonction decode ():

for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')
0
répondu Matan Hugi 2018-05-16 07:23:00