TypeError:Python3でファイルに書き込むときに「str」ではなく、バイトのようなオブジェクトが必要です


590

私はごく最近Py 3.5に移行しました。このコードは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

3.5にアップグレードすると、次のようになります。

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

最終行のエラー(パターン検索コード)。

私は.decode()ステートメントのどちらかの側で関数を使用しようとしました、また試しました:

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

- 無駄に。

ほぼすべての2:3問題を迅速に解決できましたが、この小さな発言が私を悩ませています。


11
ファイルをバイナリモードで開いてテキストとして扱うのはなぜですか?
Martijn Pieters

4
@MartijnPietersファイルオープンモードを見つけてくれてありがとう!それをテキストモードに変更すると問題が解決しました...コードはPy2kで長年にわたって確実に機能していました...
masroore


10
私もリクエストがresult = requests.getあり、それを試みているところでこれに遭遇していますx = result.content.split("\n")。それresult.contentが文字列で.split()あり、バイトのようなオブジェクトを必要としていることを意味しているように見えるので、私はエラーメッセージに少し混乱しています。(「Aオブジェクトが必要とされるバイト状ではなく、「STR」 ')..

回答:


553

ファイルをバイナリモードで開きました。

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

つまり、ファイルから読み込まれたすべてのデータはbytes、ではなくオブジェクトとして返されますstr。その後、包含テストで文字列を使用することはできません。

if 'some-pattern' in tmp: continue

代わりbytesにテストするオブジェクトを使用する必要がありますtmp

if b'some-pattern' in tmp: continue

または、'rb'モードをに置き換えて、ファイルをテキストファイルとして開きます'r'


12
PPLがリンクしているさまざまなドキュメントを見ると、デフォルトの文字列がバイトであったのに対し、Py2ではすべてが「正常に機能している」ことがわかりますが、Py3ではデフォルトの文字列はUnicodeです。特に ネットワーク、バイト文字列が標準なので、b / w Unicodeとバイト文字列(en / decode)を移動する方法を学ぶ必要があります。ファイルについては、区別するのに役立つ「r」と「rb」(および「w」と「a」)が用意されています。
wescpy 2017年

3
@wescpy:Python 2には'r'vs 'rb' もあり、バイナリとテキストファイルの動作を切り替えます(改行の翻訳や特定のプラットフォームでのEOFマーカーの扱いなど)。io(のPython 3でデフォルトのI / O機能を提供するだけでなく、Pythonの2で利用可能)ライブラリは、今もデコードし、デフォルトではテキストファイルは本当の変化です。
Martijn Pieters

2
@MartijnPieters:はい、同意しました。2.xでは、'b'DOS / Windowsでバイナリファイルを操作する必要がある場合にのみフラグを使用しました(バイナリはPOSIXのデフォルトであるため)。io3.xでファイルアクセスに使用する場合、二重の目的があることは良いことです。
wescpy 2017年

208

を使用して文字列をエンコードできます .encode()

例:

'Hello World'.encode()

48

すでに述べたように、バイナリモードでファイルを読み取り、バイトのリストを作成しています。次のforループでは、文字列とバイトを比較していて、コードが失敗しています。

リストへの追加中にバイトをデコードすることは機能するはずです。変更されたコードは次のようになります。

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

バイト型はPython 3で導入されたため、コードはPython 2で機能しました。Python2では、バイトのデータ型がありませんでした。

>>> s=bytes('hello')
>>> type(s)
<type 'str'>

25

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'])

これを変更すると、エラーは消えますが、ファイルに書き込むことができません(私の場合)。結局のところ、私には答えがありませんか?

ソース:^ Mを削除する方法

「rb」に変更すると、他のエラーが発生します:io.UnsupportedOperation:write


15

この小さな例の場合:ソケットのインポート

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

「GET http://www.py4inf.com/code/romeo.txt HTTP / 1.0 \ n \ n 」の前に「b」を追加すると問題が解決しました


11

一重引用符で囲まれたハードコードされた文字列値とともに、encode()関数を使用します。

例:

file.write(answers[i] + '\n'.encode())

または

line.split(' +++$+++ '.encode())

8

ファイルをバイナリモードで開きました。

次のコードはTypeErrorをスローします。「str」ではなく、バイトのようなオブジェクトが必要です。

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

次のコードが機能します。decode()関数を使用する必要があります。

for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')

4

ファイルをテキストとして開いてみませんか?

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

さらに、ここに公式ページのpython 3.xへのリンクがあります:https : //docs.python.org/3/library/io.html そして、これはオープン関数です:https : //docs.python.org/3 /library/functions.html#open

あなたが本当にそれをバイナリとして処理しようとしているなら、あなたの文字列をエンコードすることを検討してください。


1

文字(または文字列)をに変換しようとしたときにこのエラーが発生しました。Python2.7 bytesではコードは次のようになりました。

# -*- coding: utf-8 -*-
print( bytes('ò') )

これは、Unicode文字を処理する場合のPython 2.7の方法です。

bytesエンコーディングに追加の引数が必要なため、これはPython 3.6では機能しませんが、エンコーディングが異なると異なる結果が出力される可能性があるため、これは少しトリッキーになる可能性があります。

print( bytes('ò', 'iso_8859_1') ) # prints: b'\xf2'
print( bytes('ò', 'utf-8') ) # prints: b'\xc3\xb2'

私の場合iso_8859_1、問題を解決するためにバイトをエンコードするときに使用する必要がありました。

これが誰かを助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.