2012-08-08 4 views
5

अजगर 2.7 से यूनिकोड पाठ लोड करने के लिए सही तरीका है कुछ की तरह:पायथन 2.7 में एक समय में यूनिकोड एक पंक्ति को कैसे डीकोड कर सकता हूं? ,</p> <p>लेकिन अगर फ़ाइल बहुत है

content = open('filename').read().decode('encoding'): 
for line in content.splitlines(): 
    process(line) 

(कोई यह नहीं है उत्तर देखें अद्यतन।।) बड़ा, मैं इसे एक समय में एक पंक्ति को पढ़ना, डीकोड और संसाधित करना चाहता हूं, ताकि पूरी फ़ाइल को एक बार में स्मृति में कभी लोड नहीं किया जा सके। कुछ की तरह:

for line in open('filename'): 
    process(line.decode('encoding'))   

खुला filehandle से अधिक for पाश की यात्रा एक जनरेटर है कि एक समय में एक लाइन पढ़ता है।

क्योंकि अगर फ़ाइल utf32 एन्कोड किया गया है, उदाहरण के लिए, तो फ़ाइल में बाइट्स (हेक्स में) कुछ इस तरह दिखाई यह, हालांकि काम नहीं करता:

hello\n = 68000000(h) 65000000(e) 6c000000(l) 6c000000(l) 6f000000(o) 0a000000(\n) 

और के द्वारा किया लाइनों में विभाजित for पाश \n चरित्र की 0a बाइट पर विभाजित करता है, में (हेक्स में) जिसके परिणामस्वरूप:

lines[0] = 0x 68000000 65000000 6c000000 6c000000 6f000000 0a 
lines[1] = 0x 000000 

तो \n चरित्र का हिस्सा लाइन 1 के अंत में छोड़ दिया जाता है और शेष तीन बाइट्स में समाप्त लाइन 2 (इसके बाद जो भी पाठ वास्तव में लाइन 2 में है।) इन पंक्तियों में से किसी एक पर decode पर कॉल करने से UnicodeDecodeError में परिणाम मिलता है।

UnicodeDecodeError: 'utf32' codec can't decode byte 0x0a in position 24: truncated data 

तो, जाहिर है काफी, 0a बाइट्स पर एक यूनिकोड बाइट धारा बंटवारे नहीं यह लाइनों में विभाजित करने के लिए सही तरीका है। इसके बजाय मुझे पूर्ण चार-बाइट न्यूलाइन कैरेक्टर (0x0a000000) की घटनाओं पर विभाजित होना चाहिए। हालांकि, मुझे लगता है कि इन वर्णों का पता लगाने का सही तरीका बाइट स्ट्रीम को यूनिकोड स्ट्रिंग में डीकोड करना है और \n वर्णों को ढूंढना है - और पूर्ण स्ट्रीम का यह डिकोडिंग बिल्कुल ऑपरेशन है जिसे मैं टालने का प्रयास कर रहा हूं।

यह असामान्य आवश्यकता नहीं हो सकती है। इसे संभालने का सही तरीका क्या है?

+1

क्या आपने codecs.open() विधि का उपयोग कर फ़ाइल पढ़ने का प्रयास किया था? –

+0

@ मौलवर्फन, मुझे नहीं पता था कि यह अस्तित्व में था! लेकिन अब मैं करता हूँ। धन्यवाद। –

उत्तर

1

codecs.open itself notes that io.open is a better option (नोट लिंक लक्ष्य से ऊपर है)। यह बहिष्कृत नहीं है, बल्कि केवल इसलिए कि यह कुछ गूढ़ उपयोगों (बाइट्स-> बाइट कोडेक्स) का समर्थन करता है।

io.open is available in Python 2.6 and higher, और के रूप में ही व्यवहार प्रदान करता है Py3 के अंतर्निहित open, बेहतर अनुकूलित है, और codecs.open तरह दुर्व्यवहार नहीं है जब यह लाइन न खत्म होने वाली रूपांतरण जैसे सामान के लिए आता है। codecs.open का उपयोग करने का एकमात्र कारण यह है कि यदि आपको पाइथन 2.5 और इससे पहले का समर्थन करने की आवश्यकता है, अन्यथा, io.open कड़ाई से बेहतर है।

import io 

# Use with statement for guaranteed, predictable cleanup 
with io.open('filename', encoding='utf-32') as f: 
    for line in f: 
     process(line) 

संयोग से, आप एक सहज डिकोडिंग पाठ आधारित वस्तु using io.TextIOWrapper के लिए किसी भी पहले से ही खुला बाइनरी फ़ाइल जैसी वस्तु में बदल सकते हैं, इसलिए यदि किसी और आप द्विआधारी मोड में किसी मौजूदा फ़ाइल जैसी वस्तु प्रदान करता है, तब भी आप कर सकते हैं लाइन डिकोडिंग द्वारा लाइन के साथ अंतर्निहित रूप से करें:

def process_file(f): 
    if 'b' in f.mode: # Or some better test... 
     f = io.TextIOWrapper(f, encoding='utf-32') 
    for line in f: 
     process(line) 
4

कोडेक मॉड्यूल उपयोग करके देखें:

for line in codecs.open(filename, encoding='utf32'): 
    do_something(line) 
+0

मैंने @ साइमन का जवाब चुना है 'क्योंकि उसके पास कम अंक हैं, लेकिन एक अपवर्त है। धन्यवाद! –

+0

हू? अब आपके पास केवल एक बिंदु है! क्या हुआ!?!?! –

7

कैसे somethng तरह की कोशिश कर के बारे में:

for line in codecs.open("filename", "rt", "utf32"): 
    print line 

मुझे लगता है कि यह काम करना चाहिए।

codecs मॉड्यूल आपके लिए अनुवाद करना चाहिए।

+0

पाठक! इस पृष्ठ के निचले भाग के पास शैडोरेंजर का निम्न-बिंदु उत्तर भी देखें: "codecs.open दस्तावेज़ नोट करते हैं कि io.open एक बेहतर विकल्प है" ... –

1

बजाय खुले builtin की codecs.open उपयोग:

import codecs 
for line in codecs.open('filename', encoding='encoding'): 
    print repr(line) 

http://docs.python.org/library/codecs.html#codecs.open

बेशक

, मैं अपने ध्यान से तैयार stackoverflow सवाल खत्म करने के बाद यह मात्र क्षणों की खोज की।

+0

@jamylak, मेरे कमजोर कोड को ठीक करने के लिए धन्यवाद। –

+0

कोई समस्या नहीं है लेकिन मैंने केवल इंडेंट को ठीक किया है :) – jamylak

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