Python3의 StringIO


474

Python 3.2.1을 사용하고 있으며 StringIO모듈을 가져올 수 없습니다 . 내가 사용 io.StringIO하고 그것은 작동하지만, 나는 그것을 사용할 수 없습니다 numpy의 ' genfromtxt같은 :

x="1 3\n 4.5 8"        
numpy.genfromtxt(io.StringIO(x))

다음과 같은 오류가 발생합니다.

TypeError: Can't convert 'bytes' object to str implicitly  

내가 쓸 때 import StringIO그것이 말하는

ImportError: No module named 'StringIO'

답변:


773

import StringIO를 작성할 때 그러한 모듈이 없다고 말합니다.

에서 의 새로운에서 파이썬 3.0 :

StringIOcStringIO모듈은 사라입니다. 대신, 수입 io 모듈과 사용 io.StringIO또는 io.BytesIO각각 텍스트와 데이터를.

.


Python 3 (caveat emptor)에서도 작동하도록 일부 Python 2 코드를 수정하는 유용한 방법 :

try:
    from StringIO import StringIO ## for Python 2
except ImportError:
    from io import StringIO ## for Python 3

참고 :이 예제는 질문의 주요 이슈와 접할 수 있으며 누락 된 StringIO모듈을 일반적으로 처리 할 때 고려해야 할 사항으로 만 포함됩니다 . 메시지 TypeError: Can't convert 'bytes' object to str implicitly에 대한 직접적인 해결책 은 이 답변을 참조하십시오 .


13
이것들을 언급 할 가치가 있으므로 TypeError,이 변경을 분리하면 s (문자열 인수가 예상되고 '바이트'를 얻음)로 끝날 수 있습니다 . 파이썬 3에서 btyes와 str (유니 코드)을주의해서 구별해야합니다.
Andy Hayden

7
나 같은 newbs의 경우 : io import에서 StringIO는 io.StringIO ()가 아니라 StringIO ()로 호출한다는 것을 의미합니다.
Noumenon

11
실제로 Python 2 및 3과 호환되는 방법from io import StringIO
Oleh Prypin

8
이것은 파이썬 3의 numpy.genfromtxt ()에 대한 잘못된 것입니다. Roman Shapovalov의 답변을 참조하십시오.
Bill Huang

2
@nobar : 후자. 원래 질문은 python 3.x를 사용하는데, 여기서는 모듈 StringIO이 사라지고 from io import BytesIO대신 적용되어야합니다. 파이썬 3.5 @ 이클립스 pyDev + win7 x64에서 직접 테스트했습니다. 내가 고마워했다면 알려주십시오.
Bill Huang


70

파이썬 3 numpy.genfromtxt에서는 바이트 스트림이 필요합니다. 다음을 사용하십시오.

numpy.genfromtxt(io.BytesIO(x.encode()))

24

질문에 대해서는 OP, 답변에 대해서는 Roman에게 감사합니다. 나는 이것을 찾기 위해 조금만 검색해야했다. 다음이 다른 사람들에게 도움이되기를 바랍니다.

파이썬 2.7

참조 : https://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

import numpy as np
from StringIO import StringIO

data = "1, abc , 2\n 3, xxx, 4"

print type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
 ['3' 'xxx' '4']]
"""

print '\n', type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

파이썬 3.5 :

import numpy as np
from io import StringIO
import io

data = "1, abc , 2\n 3, xxx, 4"
#print(data)
"""
1, abc , 2
 3, xxx, 4
"""

#print(type(data))
"""
<class 'str'>
"""

#np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
# TypeError: Can't convert 'bytes' object to str implicitly

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", dtype="|S3", autostrip=True))
"""
[[b'1' b'abc' b'2']
 [b'3' b'xxx' b'4']]
"""

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

곁에:

dtype = "| Sx", 여기서 x = {1, 2, 3, ...} 중 하나 :

dtypes. 파이썬에서 S1과 S2의 차이점

"S1 및 | S2 문자열은 데이터 유형 디스크립터입니다. 첫 번째는 배열이 길이가 1 인 문자열을 보유하고 두 번째가 길이가 2 인 것을 의미합니다. ..."



17

Roman Shapovalov의 코드는 Python 3.x 및 Python 2.6 / 2.7에서 작동해야합니다. 다음은 완전한 예입니다.

import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))

산출:

array([[ 1. ,  3. ],
       [ 4.5,  8. ]])

Python 3.x에 대한 설명 :

  • numpy.genfromtxt 바이트 스트림 (유니 코드 대신 바이트로 해석되는 파일과 유사한 객체)을 사용합니다.
  • io.BytesIO바이트 문자열을 받아서 바이트 스트림을 반환합니다. io.StringIO반면에 유니 코드 문자열을 가져와 유니 코드 스트림을 반환합니다.
  • x 파이썬 3.x에서 유니 코드 문자열 인 문자열 리터럴을 할당받습니다.
  • encode()유니 코드 문자열을 가져 와서 x바이트 문자열을 io.BytesIO만들어 유효한 인수 를 제공 합니다.

Python 2.6 / 2.7의 유일한 차이점 x은 바이트 문자열 ( from __future__ import unicode_literals사용되지 않은 것으로 가정 )이며 encode()바이트 문자열 을 가져와 x여전히 동일한 바이트 문자열을 만드는 것입니다. 결과는 같습니다.


이것은에 관한 SO의 가장 인기있는 질문 중 하나이므로 StringIOimport 문과 다른 Python 버전에 대한 추가 설명이 있습니다.

다음은 문자열을 가져와 스트림을 반환하는 클래스입니다.

  • io.BytesIO(Python 2.6, 2.7 및 3.x)-바이트 문자열을 사용합니다. 바이트 스트림을 리턴합니다.
  • io.StringIO(Python 2.6, 2.7 및 3.x)-유니 코드 문자열을받습니다. 유니 코드 스트림을 반환합니다.
  • StringIO.StringIO(Python 2.x)-바이트 문자열 또는 유니 코드 문자열을받습니다. 바이트 문자열 인 경우 바이트 스트림을 반환합니다. 유니 코드 문자열 인 경우 유니 코드 스트림을 반환합니다.
  • cStringIO.StringIO(Python 2.x)-더 빠른 버전 StringIO.StringIO이지만 ASCII가 아닌 문자가 포함 된 유니 코드 문자열을 사용할 수 없습니다.

참고 StringIO.StringIO로 가져온 from StringIO import StringIO후, 사용 StringIO(...). 그 중 하나이거나을 import StringIO사용 StringIO.StringIO(...)합니다. 모듈 이름과 클래스 이름은 동일합니다. 그런 datetime식으로 비슷합니다 .

지원되는 Python 버전에 따라 사용 대상 :

  • : 당신은 단지 파이썬 3.x를 지원하는 경우 그냥 사용 io.BytesIO또는 io.StringIO종류의 데이터로 작업중인 내용에 따라.

  • : 당신이 모두 파이썬 2.6 / 2.7 및 3.x를 지원하는 경우, 또는 2.6 / 2.7에서 3.X에 코드를 전환하려고하는 가장 쉬운 옵션은 사용에 여전히 io.BytesIOio.StringIO. 하지만 StringIO.StringIO2.6 / 2.7 선호 보인다 따라서 유연하고, 그 유연성은 3.x를에 명시됩니다 버그 마스크 수 예를 들어, StringIO.StringIO또는io.StringIO 파이썬 버전 의존 있지만 실제로 바이트 문자열을 전달하고 있었으므로 Python 3.x에서 테스트하려고 할 때 실패하고 수정해야했습니다.

    사용의 또 다른 장점은 io.StringIO범용 줄 바꾸기를 지원한다는 것입니다. 당신이 키워드 인수를 전달하는 경우 newline=''io.StringIO, 그것의에 라인을 분할 할 수있을 것이다 \n, \r\n또는 \r. 나는 그것이 특히 StringIO.StringIO넘어 질 것이라는 것을 알았다 \r.

    당신이 가져 오는 경우하는 것으로 BytesIOStringIO에서 six, 당신은 얻을 StringIO.StringIO에서 파이썬 2.x 및 적절한 클래스에 io파이썬 3.x에서의 이전 단락의 평가에 동의하는 경우 실제로는 피하고 대신 six가져와야하는 io경우입니다.

  • Python 2.5 이하 및 3.x를 지원하는 경우 :StringIO.StringIO 2.5 이하 가 필요 하므로을 사용할 수도 있습니다 six. 그러나 일반적으로 2.5와 3.x를 모두 지원하는 것은 매우 어렵다는 것을 알고 있으므로 가능하면 가장 낮은 지원 버전을 2.6으로 높이는 것이 좋습니다.


7

여기 에서 예제를 파이썬 3.5.2와 함께 사용하려면 다음과 같이 다시 작성할 수 있습니다.

import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6") 
import numpy
numpy.genfromtxt(data, delimiter=",")

변경 이유는 파일의 내용이 어떻게 든 해독 될 때까지 텍스트를 만들지 않는 데이터 (바이트)에 있기 때문일 수 있습니다. genfrombytes보다 더 나은 이름 일 수 있습니다 genfromtxt.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.