2011-04-11 12 views
20

एक ज़िप फ़ाइल के अंदर एक CSV फ़ाइल को पढ़ने के लिए एक सरल कार्यक्रम अजगर 2.7 में काम करता है, लेकिन अजगर में 3,2py3k: आप एक ज़िप फ़ाइल के अंदर फ़ाइल को पाठ के रूप में कैसे पढ़ते हैं, बाइट्स नहीं?

$ 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?) 

तो अजगर 3 में csv मॉड्यूल एक पाठ फ़ाइल को देखना चाहता है नहीं है, लेकिन zipfile.ZipFile.open एक zipfile.ZipExtFile रिटर्न जिसे हमेशा बाइनरी डेटा के रूप में माना जाता है।

कोई इस काम को पायथन 3 में कैसे बनाता है?

उत्तर

22

मैं सिर्फ देखा है कि Lennart's answer अजगर 3.1 साथ काम नहीं किया है, लेकिन यह Python 3.2 साथ काम करता है। उन्होंने पाइथन 3.2 में zipfile.ZipExtFile बढ़ाया है (release notes देखें)। ये परिवर्तन zipfile.ZipExtFileio.TextWrapper के साथ अच्छी तरह से काम करने के लिए प्रकट होते हैं।

संयोग से, यह पाइथन 3.1 में काम करता है, अगर आप बंदर-पैच zipfile.ZipExtFile पर हैकी लाइनों को अनदेखा करते हैं, तो यह नहीं कि मैं इस प्रकार की हैकर की सिफारिश करूंगा। मैं इसे केवल पायथन 3.2 में किए गए कार्यों के सार को स्पष्ट करने के लिए शामिल करता हूं ताकि चीजें अच्छी तरह से काम कर सकें।

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

अगर मैं py3k < 3.2 का समर्थन करने के लिए किया था, तो मैं my other answer में समाधान के साथ जाना होगा।

+0

io.TextIOWrapper() एफटीडब्ल्यू !!! धन्यवाद। –

5

आप इसे io.TextIOWrapper में लपेट सकते हैं।

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

काम करना चाहिए।

1

Lennart's answer सही रास्ते पर है (धन्यवाद, Lennart, मैं अपने जवाब को वोट किया है) और यह लगभग काम करता है:

$ 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 

समस्या हो कि io.TextWrapper के पहले आवश्यक पैरामीटर एक है प्रकट होता है बफर; फ़ाइल ऑब्जेक्ट नहीं।

यह काम करने के लिए प्रकट होता है:

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

यह एक छोटे से जटिल लगता है और यह भी एक पूरे (शायद बहुत बड़ा) स्मृति में ज़िप फ़ाइल में पढ़ने के लिए करने के लिए कष्टप्रद लगता है। कोई बेहतर तरीका?

यहाँ यह कार्रवाई में है:

$ 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 
+0

[मुझसे एक और जवाब] (http://stackoverflow.com/questions/5627954/py3k-how-do-you-read-a-file-inside-a-zip-file-as-text-not- बाइट्स/5639 9 60 # 5639 9 60) एक बेहतर तरीका बताता है जो पायथन 3.2 में काम करता है। –

संबंधित मुद्दे