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.
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'
.
vous pouvez encoder votre chaîne en utilisant .encode()
exemple:
'Hello World'.encode()
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'>
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
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
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.
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')