StringIO în Python3

Eu sunt, folosind Python 3.2.1 și nu pot't importa StringIO module. Eu folosesc io.StringIO și funcționează, dar nu pot't folosi cu numpy's genfromtxt astfel:

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

I a lua următoarea eroare:

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

și când scriu import StringIO se spune

ImportError: No module named 'StringIO'

când scriu import StringIO se spune că nu există nici un astfel de modul.

De Ce este Nou În Python 3.0:

StringIO " și " cStringIO module sunt plecat. În schimb, importul de io modulul și de a folosi `io.StringIO " sau " io.BytesIO pentru text și date respectiv.

.


Un eventual utile metoda de stabilire a unor Python 2 cod pentru a lucra, de asemenea, în Python 3 (caveat emptor):

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

Notă: Acest exemplu poate fi tangent la problema principală a întrebării și este inclusă doar ca ceva să ia în considerare atunci când generic abordarea lipsește StringIO` module. Pentru o mai directă soluție mesajul TypeError: Poate't converti 'bytes' obiect la str implicit, a se vedea acest răspuns.

Comentarii (14)

În cazul meu, am folosit:

from io import StringIO
Comentarii (0)

Pe Python 3 numpy.genfromtxt se așteaptă la un flux de octeți. Utilizați următoarele:

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

Multumesc OP pentru intrebarea ta, și Roman pentru răspunsul dumneavoastră. Am avut pentru a căuta un pic pentru a găsi acest lucru; sper că următoarele ajută pe alții.

Python 2.7

A se vedea: 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)
"""

"""

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

print '\n', type(data)
"""

"""

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

Python 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))
"""

"""

#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.]]
"""

O parte:

dtype="|Sx", unde x = oricare dintre { 1, 2, 3, ...}:

https://stackoverflow.com/questions/14790130/dtypes-difference-between-s1-and-s2-in-python

" |S1 și |S2 siruri de caractere sunt date de tip descriptori; prima înseamnă matrice deține siruri de caractere de lungime 1, al doilea de lungime 2. ..."

Comentarii (0)

Puteți utiliza StringIO de la șase modulul:

import six
import numpy

x = "1 3\n 4.5 8"
numpy.genfromtxt(six.StringIO(x))
Comentarii (0)

Roman Shapovalov's cod ar trebui să lucreze în Python 3.x, precum Python 2.6/2.7. Aici este din nou cu complet exemplu:

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

Ieșire:

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

Explicație pentru Python 3.x:

  • numpy.genfromtxt nevoie de un flux de octeți (un fișier ca obiect interpretat ca octeți în loc de Unicode).
  • io.BytesIO nevoie de un octet string și returnează un flux de octeți. io.StringIO, pe de altă parte, ar lua un șir Unicode și și să se întoarcă un Unicode stream.
  • "x" se atribuie un string literal, care în Python 3.x este un șir Unicode.
  • encode() ia Unicode string " x " și face un octet string afară de ea, astfel, da io.BytesIO un argument valid.

Singura diferență pentru Python 2.6/2.7 este că " x "este un octet string (presupunând din viitoarele import unicode_literalsnu este folosit), și, apoi, pentru a codifica() ia octet string" x " și încă face același octet string din ea. Deci, rezultatul este același.


Deoarece aceasta este una dintre ATÂT de's cele mai populare întrebări cu privire la StringIO, aici's o explicație mai multe pe declarații de import și diferite Python versiuni.

Aici sunt clase care ia un șir de caractere și să se întoarcă un flux:

  • io.BytesIO (Python 2.6, 2.7, și 3.x) - Nevoie de un octet string. Returnează un flux de octeți.
  • io.StringIO (Python 2.6, 2.7, și 3.x) - Are un șir Unicode. Returnează un Unicode stream.
  • StringIO.StringIO (Python 2.x) - Nevoie de un octet string sau Unicode string. Dacă octet de coarde, returnează un flux de octeți. Dacă Unicode string, returnează un Unicode stream.
  • cStringIO.StringIO (Python 2.x) - versiune mai Rapidă de StringIO.StringIO`, dar poate't ia siruri de caractere Unicode care conțin caractere non-ASCII.

Rețineți că StringIO.StringIO este importat ca de StringIO import StringIO, apoi folosit caStringIO(...). Ori asta, ori te faci import StringIO și de a folosi apoi StringIO.StringIO(...). Modulul nume și nume de clasă doar se întâmplă să fie același. L's similare pentru a "datetime" așa.

Ce să folosească, în funcție de susținut Python versiuni:

  • Dacă aveți doar suport Python 3.x: utilizați Doar io.BytesIO " sau " io.StringIO în funcție de ce fel de date're de lucru cu.

  • Dacă vă sprijini atât Python 2.6/2.7 si 3.x, sau încearcă să tranziție codul de 2.6/2.7-3.x: Cea mai simplă opțiune este de a utiliza io.BytesIO " sau " io.StringIO. Deși StringIO.StringIO este flexibil și, prin urmare, pare de preferat pentru 2.6/2.7, că flexibilitatea ar putea masca de bug-uri, care se vor manifesta în 3.x. De exemplu, am avut un cod care a folosit StringIO.StringIO " sau " io.StringIO în funcție de versiunea Python, dar eu chiar am fost in trecere un octet de coarde, așa că atunci când am ajuns în jurul să-l testeze în Python 3.x nu a reușit și a trebuit să fie reparat.

Un alt avantaj al folosind io.StringIO este suportul universal pentru linii noi. Dacă treci de cuvinte cheie argument newline='' în io.StringIO, va fi capabil de a împărți liniile de pe orice de \n, \r\n, sau \r. Am constatat că StringIO.StringIO ar excursie până la \r, în special.

Rețineți că, dacă aveți de import BytesIO " sau " StringIO de șase, te StringIO.StringIO în Python 2.x și clasa corespunzătoare deioîn Python 3.x. Dacă sunteți de acord cu alineatele anterioare' de evaluare, aceasta este de fapt un caz în care ar trebui să evite "șase" și de import de laio` în loc.

  • Dacă aveți suport Python 2.5 sau mai mic și 3.x: Te - 'll nevoie de StringIO.StringIO` de 2.5 sau mai mic, asa ca ai putea la fel de bine folosi "șase". Dar dau seama că-l's, în general, foarte dificil de a sprijini atât 2.5 și 3.x, deci ar trebui să ia în considerare lovire de jos a sprijinit versiune la 2,6 dacă la toate posibil.
Comentarii (0)

În scopul de a face exemple de aici lucra cu Python 3.5.2, puteți rescrie după cum urmează :

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

Motivul pentru această schimbare ar putea fi faptul că conținutul unui fișier este în date (bytes), care nu face textul până când a fost decodat într-un fel. genfrombytes poate fi un nume mai bun decât genfromtxt.

Comentarii (0)

încercați acest lucru

din StringIO import StringIO

x="1 3\n 4.5 8"

numpy.genfromtxt(StringIO(x))

Comentarii (0)