[python] TypeError : Python3에서 파일에 쓸 때 ‘str’이 아닌 바이트와 같은 객체가 필요합니다.

최근에 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 문제를 신속하게 해결할 수 있었지만이 작은 진술로 인해 문제가 발생했습니다.



답변

이진 모드에서 파일을 열었습니다.

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


답변

다음을 사용하여 문자열을 인코딩 할 수 있습니다 .encode()

예:

'Hello World'.encode()


답변

이미 언급했듯이 이진 모드에서 파일을 읽은 다음 바이트 목록을 만듭니다. 다음 for 루프에서 문자열을 바이트와 비교하고 코드가 실패하는 곳입니다.

목록에 추가하는 동안 바이트를 디코딩하면 작동합니다. 변경된 코드는 다음과 같아야합니다.

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

바이트 유형은 Python 3에서 도입되었으며 코드가 Python 2에서 작동하는 이유입니다. Python 2에는 바이트에 대한 데이터 유형이 없었습니다.

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


답변

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


답변

이 작은 예제의 경우 : 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()

‘GET http://www.py4inf.com/code/romeo.txt HTTP / 1.0 \ n \ n’ 앞에 “b”를 추가하면 문제가 해결되었습니다.


답변

작은 따옴표로 묶은 하드 코딩 된 문자열 값과 함께 encode () 함수를 사용하십시오.

전의:

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

또는

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


답변

이진 모드에서 파일을 열었습니다.

다음 코드는 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')