recuperar que partes online guardado fue dividir cómo como archivos archivo abrir csv python-3.x zipfile

csv - que - winrar online



py3k: ¿Cómo se lee un archivo dentro de un archivo zip como texto, no como bytes? (3)

Un sencillo programa para leer un archivo CSV dentro de un archivo zip funciona en Python 2.7, pero no en Python 3.2

$ cat test_zip_file_py3k.py import csv, sys, zipfile zip_file = zipfile.ZipFile(sys.argv[1]) items_file = zip_file.open(''items.csv'', ''rU'') for row in csv.DictReader(items_file): pass $ python2.7 test_zip_file_py3k.py ~/data.zip $ python3.2 test_zip_file_py3k.py ~/data.zip Traceback (most recent call last): File "test_zip_file_py3k.py", line 8, in <module> for row in csv.DictReader(items_file): File "/home/msabramo/run/lib/python3.2/csv.py", line 109, in __next__ self.fieldnames File "/home/msabramo/run/lib/python3.2/csv.py", line 96, in fieldnames self._fieldnames = next(self.reader) _csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

Entonces, el módulo csv en Python 3 quiere ver un archivo de texto, pero zipfile.ZipFile.open devuelve un zipfile.ZipExtFile que siempre se trata como datos binarios.

¿Cómo hace esto que funcione en Python 3?


Me di cuenta de que la respuesta de Lennart no funcionaba con Python 3.1 , pero funciona con Python 3.2 . Han mejorado zipfile.ZipExtFile en Python 3.2 (ver notas de la versión ). Estos cambios parecen hacer que zipfile.ZipExtFile funcione bien con io.TextWrapper .

Dicho sea de paso, funciona en Python 3.1, si descomenta las líneas hacky a continuación, en mono-patch zipfile.ZipExtFile , no es que yo recomendaría este tipo de hackers. Lo incluyo solo para ilustrar la esencia de lo que se hizo en Python 3.2 para que todo funcione bien.

$ cat test_zip_file_py3k.py import csv, io, sys, zipfile zip_file = zipfile.ZipFile(sys.argv[1]) items_file = zip_file.open(''items.csv'', ''rU'') # items_file.readable = lambda: True # items_file.writable = lambda: False # items_file.seekable = lambda: False # items_file.read1 = items_file.read items_file = io.TextIOWrapper(items_file) for idx, row in enumerate(csv.DictReader(items_file)): print(''Processing row {0} -- row = {1}''.format(idx, row))

Si tuviera que admitir py3k <3.2, me gustaría ir con la solución en mi otra respuesta .


Puede envolverlo en un io.TextIOWrapper .

items_file = io.TextIOWrapper(items_file, encoding=''your-encoding'', newline='''')

Deberia trabajar.


La respuesta de Lennart está en el camino correcto (gracias, Lennart, voté su respuesta) y casi funciona:

$ cat test_zip_file_py3k.py import csv, io, sys, zipfile zip_file = zipfile.ZipFile(sys.argv[1]) items_file = zip_file.open(''items.csv'', ''rU'') items_file = io.TextIOWrapper(items_file, encoding=''iso-8859-1'', newline='''') for idx, row in enumerate(csv.DictReader(items_file)): print(''Processing row {0}''.format(idx)) $ python3.1 test_zip_file_py3k.py ~/data.zip Traceback (most recent call last): File "test_zip_file_py3k.py", line 7, in <module> items_file = io.TextIOWrapper(items_file, encoding=''iso-8859-1'', newline='''') AttributeError: readable

El problema parece ser que el primer parámetro requerido de io.TextIOWrapper es un búfer ; no es un objeto de archivo

Esto parece funcionar:

items_file = io.TextIOWrapper(io.BytesIO(items_file.read()))

Esto parece un poco complejo y también parece molesto tener que leer en un archivo zip completo (tal vez enorme) en la memoria. ¿Alguna mejor manera?

Aquí está en acción:

$ cat test_zip_file_py3k.py import csv, io, sys, zipfile zip_file = zipfile.ZipFile(sys.argv[1]) items_file = zip_file.open(''items.csv'', ''rU'') items_file = io.TextIOWrapper(io.BytesIO(items_file.read())) for idx, row in enumerate(csv.DictReader(items_file)): print(''Processing row {0}''.format(idx)) $ python3.1 test_zip_file_py3k.py ~/data.zip Processing row 0 Processing row 1 Processing row 2 ... Processing row 250