web-dev-qa-db-fra.com

TypeError: un objet de type octet est requis, pas 'str' lors de l'écriture dans un fichier en Python3

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.

445
masroore

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'.

432
Martijn Pieters

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

Exemple:

'Hello World'.encode()
138
theofpa

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'>
34
Suresh

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

15
meck373

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

13
starter

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')
5
Matan Hugi

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.

3
Fernando D Jaime

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