J'ai 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, je reçois le:
TypeError: a bytes-like object is required, not 'str'
erreur sur la dernière ligne (le code de recherche de modèle).
J'ai essayé d'utiliser la fonction .decode()
de part et d'autre de l'instruction, également essayé:
if tmp.find('some-pattern') != -1: continue
- en vain.
J'ai été capable de résoudre presque tous les problèmes 2: 3 rapidement, mais cette petite déclaration m'embête.
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 renvoyées sous forme d'objets bytes
, et non de str
. Vous ne pouvez pas ensuite utiliser une chaîne dans un test de confinement:
if 'some-pattern' in tmp: continue
Vous devez utiliser un objet bytes
pour tester contre tmp
:
if b'some-pattern' in tmp: continue
ou ouvrez le fichier en tant que fichier texte en remplaçant le mode 'rb'
par 'r'
.
Vous pouvez encoder votre chaîne en utilisant .encode()
Exemple:
'Hello World'.encode()
Comme cela a déjà été mentionné, vous lisez le fichier en mode binaire, puis vous créez une liste d'octets. Dans votre boucle pour suivante, vous comparez chaîne en octets et c’est là que le code échoue.
Décoder les octets lors de l'ajout à 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 d'octets a été introduit dans Python 3 et c'est pourquoi votre code a fonctionné dans Python 2. Dans Python 2, il n'y avait pas de type de données pour les octets:
>>> s=bytes('hello')
>>> type(s)
<type 'str'>
Vous devez changer de wb en 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 modifié cela, l'erreur disparaît, mais vous ne pouvez pas écrire dans le fichier (dans mon cas). Donc après tout, je n'ai pas de réponse?
Source: Comment supprimer ^ M
Passer à 'rb' m'apporte l'autre erreur: io.UnsupportedOperation: write
pour ce petit exemple: socket d'importation
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()
ajout du "b" avant 'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n' a résolu mon problème
Vous avez ouvert le fichier en mode binaire:
Le code suivant générera une erreur TypeError: un objet de type octet 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')
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()]
De plus, voici un lien pour python 3.x sur la page officielle: https://docs.python.org/3/library/io.html Et voici la page ouverte fonction: https://docs.python.org/3/library/functions.html#open
Si vous essayez vraiment de le gérer comme un binaire, envisagez de coder votre chaîne.
Utilisez la fonction encode () avec la valeur de chaîne codée en dur donnée entre guillemets.
Ex:
file.write(answers[i] + '\n'.encode())
OR
line.split(' +++$+++ '.encode())